Ë
    ÛÓ^j»5  ã                  óÌ   — d Z ddlmZ ddlZddlmc mZ d
dd„Z	 	 d	 	 	 	 	 	 	 	 	 dd„Z		 d
	 	 	 	 	 	 	 	 	 	 	 dd„Z
	 d
	 	 	 	 	 	 	 	 	 dd„Z	 d
	 	 	 	 	 	 	 dd„Z	 d
	 	 	 	 	 	 	 dd	„Zy)uÿ  Vision utility functions for pre-computing very dynamic and
data-dependent tensors that can break model graph capturing.

All functions are standalone (no model weights) and compute tensors from
`grid_thw` + config scalars. They are used by vision encoders and can be
precomputed before `torch.compile` / `torch.export` tracing since they
use untraceable ops (`repeat_interleave`, `.tolist()`, `nonzero()`, loops).

Each `get_*` accepts an optional `kwargs` dict; if it contains the
precomputed tensor under the natural key (`"cu_seqlens"`, `"position_ids"`,
â€¦), the function pops and returns it instead of computing. Vision encoders
write `x = get_vision_x(..., kwargs=kwargs)` and the matching key is
removed from the caller's kwargs as a side-effect of the pop.
é    )ÚannotationsNc                óP  — |�|j                  dd«      x}�|S t        j                  | dd…df   | dd…df   z  | dd…df   «      j                  dt        j                  j                  «       r| j                  nt        j                  ¬«      }t        j                  |dd¬«      S )	u…  Get cumulative sequence lengths from vision grid info, or pop from `kwargs` if precomputed.

    Args:
        grid_thw: `(num_images_or_videos, 3)` â€” temporal, height, width per entry.
        kwargs: optional caller kwargs â€” if it contains `"cu_seqlens"` it is popped and returned.

    Returns:
        `cu_seqlens`: `(total_patches + 1,)` int32 cumulative sequence boundaries.
    NÚ
cu_seqlensé   é   r   )ÚdimÚdtype)r   r   )Úvalue)
ÚpopÚtorchÚrepeat_interleaveÚcumsumÚjitÚ
is_tracingr	   Úint32ÚFÚpad)Úgrid_thwÚkwargsr   s      úd/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/transformers/vision_utils.pyÚget_vision_cu_seqlensr   #   s›   € ð Ð¨V¯Z©Z¸ÀdÓ-KÐK˜zÐXØÐÜ×(Ñ(¨²!°Q°$©¸(Â1ÀaÀ4¹.Ñ)HÈ(ÒSTÐVWÐSWÉ.ÓY×`Ñ`Ø¤u§y¡y×';Ñ';Ô'=�X—^’^Ä5Ç;Á;ð aó €Jô �5‰5�˜V¨1Ô-Ð-ó    c           
     ó  — |�|j                  dd«      x}�|S | j                  }t        |t        «      r0t	        j
                  |g|¬«      j                  t        | «      «      }g }t        | j                  «       |j                  «       «      D �]e  \  \  }}}}	t	        j                  t	        j                  ||¬«      t	        j                  ||¬«      d¬«      \  }
}||	z  |	||	z  |	f}|
j                  |«      j                  dd«      j                  «       }
|j                  |«      j                  dd«      j                  «       }|rrt	        j                  ||¬«      j                  ||z  «      }|j!                  t	        j"                  ||
j%                  |«      |j%                  |«      gd¬	«      «       �Œ.|j!                  t	        j"                  |
|gd¬	«      j%                  |d«      «       �Œh t	        j&                  |d
¬	«      S )u  Get position IDs for vision rotary embeddings, or pop from `kwargs` if precomputed.

    Args:
        grid_thw: `(num_images_or_videos, 3)`
        spatial_merge_size: merge block size â€” either a single `int` (same for all images)
            or a `(num_images_or_videos,)` tensor (per-image).
        kwargs: optional caller kwargs â€” if it contains `"position_ids"` it is popped and returned.
        include_temporal: when ``True``, prepend a temporal-index column and return
            `(total_tokens, 3)` â€” for encoders whose rotary embedding rotates T/H/W axes
            (minimax_m3_vl). When ``False`` (default), return `(total_tokens, 2)` for the
            2-axis (h, w) case (qwen2_5_vl / qwen3_vl / glm4v / paddleocr_vl); the h/w
            indices are still repeated ``t`` times for video inputs.

    Returns:
        `position_ids`: `(total_tokens, 3)` long if ``include_temporal`` else `(total_tokens, 2)`,
        with the spatial indices laid out block-major over ``mÃ—m`` spatial-merge blocks.
    NÚposition_ids©ÚdeviceÚij)Úindexingr   r   éÿÿÿÿ©r   r   )r   r   Ú
isinstanceÚintr   ÚtensorÚexpandÚlenÚzipÚtolistÚmeshgridÚarangeÚreshapeÚ	transposeÚflattenr   ÚappendÚstackÚrepeatÚcat)r   Úspatial_merge_sizeÚinclude_temporalr   r   r   ÚtÚhÚwÚ
merge_sizeÚhpos_idsÚwpos_idsÚblock_shapeÚtpos_idss                 r   Úget_vision_position_idsr;   5   sÅ  € ð. Ð¨v¯z©z¸.È$Ó/OÐO˜|Ð\ØÐà�_‰_€FÜÐ$¤cÔ*Ü"Ÿ\™\Ð+=Ð*>ÀvÔN×UÑUÔVYÐZbÓVcÓdÐà€LÜ!$ X§_¡_Ó%6Ð8J×8QÑ8QÓ8SÓ!Tó XÑ‰	ˆˆAˆq�:Ü"Ÿ^™^Ü�L‰L˜ 6Ô*Ü�L‰L˜ 6Ô*Øô
Ñˆ�(ð
 ˜J‘¨
°A¸±OÀZÐPˆØ×#Ñ# KÓ0×:Ñ:¸1¸aÓ@×HÑHÓJˆØ×#Ñ# KÓ0×:Ñ:¸1¸aÓ@×HÑHÓJˆÙÜ—|‘| A¨fÔ5×GÑGÈÈAÉÓNˆHØ×Ñ¤§¡¨X°x·±ÀqÓ7IÈ8Ï?É?Ð[\ÓK]Ð,^ÐdfÔ gÖhà×Ñ¤§¡¨X°xÐ,@ÀbÔ I× PÑ PÐQRÐTUÓ VÖWðXô �9‰9�\ qÔ)Ð)r   c                óL  — |�,|j                  dd«      }|j                  dd«      }|�|�||fS g }dg}d}||z  |z  }|dz  }	| j                  «       D �]o  \  }
}}t        |
«      t        |«      t        |«      }}}
||z  }||z  }t        j                  |
|z  |z  «      j                  |
||«      }|||z  z
  }|||z  z
  }||z   |z  }||z   |z  }t        j                  |d|d|fdd«      }|j                  |
||||«      }|j                  ddd	dd
«      j                  |
||z  ||«      }|dk7  j                  dd	g«      j                  d«      }|j                  d«      }||dk7     }|j                  ||z   «       |j                  d«      |	z  |d   z   }|j                  |j                  «       «       ||
|z  |z  z  }�Œr t        j                  |d¬«      }t        j                  || j                  t        j                   ¬«      }t        j"                  |«      }||fS )u   Get window attention indices, or pop `"window_index"`/`"cu_window_seqlens"` from `kwargs` if both precomputed.

    Args:
        grid_thw: `(num_images_or_videos, 3)`
        spatial_merge_size: merge block size from vision config.
        window_size: window size from vision config.
        patch_size: patch size from vision config.
        kwargs: optional caller kwargs â€” if it contains both `"window_index"` and `"cu_window_seqlens"` they are popped and returned.

    Returns:
        `window_index`: `(total_tokens,)` long â€” reorder indices for windowed attention.
        `cu_window_seqlens`: `(num_windows + 1,)` int32 â€” cumulative window boundaries.
    NÚwindow_indexÚcu_window_seqlensr   r   Úconstantiœÿÿÿr   é   é   r   r    )r   r	   )r   r'   r"   r   r)   r*   r   r   ÚpermuteÚsumr-   r   Úextendr0   r#   r   r   Úunique_consecutive)r   r1   Úwindow_sizeÚ
patch_sizer   r=   r>   Úwindow_index_idÚvit_merger_window_sizeÚspatial_merge_unitÚgrid_tÚgrid_hÚgrid_wÚ
llm_grid_hÚ
llm_grid_wÚindexÚpad_hÚpad_wÚnum_windows_hÚnum_windows_wÚindex_paddedÚseqlensÚ	index_newÚcu_seqlens_tmps                           r   Úget_vision_window_indexrY   f   s‡  € ð( ÐØ—z‘z .°$Ó7ˆØ"ŸJ™JÐ':¸DÓAÐØÐ#Ð(9Ð(EØÐ!2Ð2Ð2Ø€LØ ˜cÐØ€OØ(Ð,>Ñ>À*ÑLÐØ+¨QÑ.Ðà"*§/¡/Ó"3ó <Ñˆ�˜Ü!$ V£¬c°&«k¼3¸v»;˜�ˆØÐ1Ñ1ˆ
ØÐ1Ñ1ˆ
Ü—‘˜V jÑ0°:Ñ=Ó>×FÑFÀvÈzÐ[eÓfˆØ&¨Ð6LÑ)LÑLˆØ&¨Ð6LÑ)LÑLˆØ# eÑ+Ð0FÑFˆØ# eÑ+Ð0FÑFˆÜ—u‘u˜U Q¨¨q°%Ð$8¸*ÀdÓKˆØ#×+Ñ+Ø�MÐ#9¸=ÐJ`ó
ˆð $×+Ñ+¨A¨q°!°Q¸Ó:×BÑBØ�M MÑ1Ð3IÐKaó
ˆð   4Ñ'×,Ñ,¨a°¨VÓ4×<Ñ<¸RÓ@ˆØ#×+Ñ+¨BÓ/ˆØ  °Ñ!5Ñ6ˆ	Ø×Ñ˜I¨Ñ7Ô8Ø Ÿ™¨Ó*Ð-?Ñ?ÐBSÐTVÑBWÑWˆØ× Ñ  ×!6Ñ!6Ó!8Ô9Ø˜6 JÑ.°Ñ;Ñ;Šð-<ô0 —9‘9˜\¨qÔ1€LÜŸ™Ð%6¸x¿¹ÔV[×VaÑVaÔbÐÜ×0Ñ0Ð1BÓCÐØÐ*Ð*Ð*r   c           	     ó|  — |�,|j                  dd«      }|j                  dd«      }|�|�||fS |}|}| j                  }t        d«      D �	cg c]  }	g ‘Œ }
}	t        d«      D �	cg c]  }	g ‘Œ }}	| j                  «       D �]·  \  }}}t	        |«      t	        |«      t	        |«      }}}t        j                  d|dz
  ||¬«      }t        j                  d|dz
  ||¬«      }|j	                  «       }|j	                  «       }|dz   j                  |dz
  ¬«      }|dz   j                  |dz
  ¬«      }||z
  }||z
  }||z  }||z  }|dd…df   |ddd…f   z   j                  «       |dd…df   |ddd…f   z   j                  «       |dd…df   |ddd…f   z   j                  «       |dd…df   |ddd…f   z   j                  «       g}d|z
  dd…df   d|z
  ddd…f   z  j                  «       d|z
  dd…df   |ddd…f   z  j                  «       |dd…df   d|z
  ddd…f   z  j                  «       |dd…df   |ddd…f   z  j                  «       g}t        j                  ||¬«      j                  ||z  |«      }t        j                  ||¬«      j                  ||z  |«      }|dd…dd…ddf   |z  |dddd…dd…f   z   j                  dd	«      j                  «       j                  |«      }t        d«      D ]6  }|
|   j                  ||   |   «       ||   j                  ||   |   «       Œ8 �Œº t        j                  |
D �cg c]  }t        j                  |«      ‘Œ c}«      }t        j                  |D �cg c]  }t        j                  |«      ‘Œ c}«      }||fS c c}	w c c}	w c c}w c c}w )
už  Get bilinear interpolation indices/weights, or pop `"bilinear_indices"`/`"bilinear_weights"` from `kwargs` if both precomputed.

    Args:
        grid_thw: `(num_images_or_videos, 3)`
        num_grid_per_side: `int(num_position_embeddings ** 0.5)` from vision config.
        spatial_merge_size: merge block size from vision config.
        kwargs: optional caller kwargs â€” if it contains both `"bilinear_indices"` and `"bilinear_weights"` they are popped and returned.

    Returns:
        `bilinear_indices`: `(4, total_thw)` long â€” bilinear corner indices into pos_embed table.
        `bilinear_weights`: `(4, total_thw)` float â€” interpolation weights.
    NÚbilinear_indicesÚbilinear_weightsrA   r   r   r   )Úmaxr   )r   r   Úranger'   r"   r   ÚlinspaceÚclampr,   r)   Úviewr+   r/   r-   r.   r0   ) r   Únum_grid_per_sider1   r   r[   r\   Úsider6   r   Ú_Ú	idx_partsÚweight_partsr3   r4   r5   Úh_gridÚw_gridÚh_floorÚw_floorÚh_ceilÚw_ceilÚh_fracÚw_fracÚh_floor_offsetÚh_ceil_offsetÚcorner_indicesÚcorner_weightsÚh_idxÚw_idxÚreorderÚiÚps                                    r   Ú'get_vision_bilinear_indices_and_weightsrx   £   sØ  € ð$ ÐØ!Ÿ:™:Ð&8¸$Ó?ÐØ!Ÿ:™:Ð&8¸$Ó?ÐØÐ'Ð,<Ð,HØ#Ð%5Ð5Ð5Ø€DØ#€JØ�_‰_€Fä7<¸Q³xÖ*@°!ª2Ð*@€IÐ*@Ü:?À»(Ö-C°QªbÐ-C€LÐ-Cà—?‘?Ó$ó $?‰ˆˆ1ˆaÜ�a“&œ#˜a›&¤# a£&ˆaˆ1ˆä—‘  4¨!¡8¨Q°vÔ>ˆÜ—‘  4¨!¡8¨Q°vÔ>ˆà—*‘*“,ˆØ—*‘*“,ˆØ˜A‘+×$Ñ$¨°©Ð$Ó2ˆØ˜A‘+×$Ñ$¨°©Ð$Ó2ˆà˜'Ñ!ˆØ˜'Ñ!ˆà  4™ˆØ ™ˆð šA˜t˜GÑ$ w¨t²Q¨wÑ'7Ñ7×@Ñ@ÓBØšA˜t˜GÑ$ v¨d²A¨g¡Ñ6×?Ñ?ÓAØš1˜d˜7Ñ# g¨d²A¨gÑ&6Ñ6×?Ñ?ÓAØš1˜d˜7Ñ# f¨T²1¨W¡oÑ5×>Ñ>Ó@ð	
ˆð �&‰jš!˜T˜'Ñ" a¨&¡j°$º°'Ñ%:Ñ:×CÑCÓEØ�&‰jš!˜T˜'Ñ" V¨D²!¨G¡_Ñ4×=Ñ=Ó?Ø’A�t�G‰_  F¡
¨D²!¨GÑ4Ñ4×=Ñ=Ó?Ø’A�t�G‰_˜v dªA g™Ñ.×7Ñ7Ó9ð	
ˆô —‘˜Q vÔ.×3Ñ3°A¸±OÀZÓPˆÜ—‘˜Q vÔ.×3Ñ3°A¸±OÀZÓPˆØššA˜t TÐ)Ñ*¨QÑ.°°t¸TÂ1ÂaÐ7GÑ1HÑH×SÑSÐTUÐWXÓY×aÑaÓc×jÑjÐklÓmˆä�q“ò 	?ˆAØ�a‰L×Ñ ¨qÑ 1°'Ñ :Ô;Ø˜‰O×"Ñ" >°!Ñ#4°WÑ#=Õ>ò	?ðE$?ôL —{‘{¸)Ö#D°Q¤E§I¡I¨a¥LÒ#DÓEÐÜ—{‘{¸,Ö#G°Q¤E§I¡I¨a¥LÒ#GÓHÐØÐ-Ð-Ð-ùòW +AùÚ-CùòP $EùÚ#Gs   Á	N*Á$	N/ÍN4ÎN9c                ó2  — |�|j                  dd«      x}�|S | j                  }t        j                  d|z  dd|z  |¬«      }g }| j	                  «       D ]«  \  }}t        |«      t        |«      }}t        j                  ||¬«      |z  }	t        j                  ||¬«      |z  }
t        j                  |	|d¬«      }t        j                  |
|d¬«      }|j                  |dd…df   |z  |z   j                  «       «       Œ­ t        j                  |«      S )u  Get nearest-neighbor position IDs into a `num_patches_per_side**2` 2-D table, or pop
    from `kwargs` if precomputed.

    For each image of size `(h, w)`, maps fractional grid coordinates `i/h` to the nearest
    bucket on a `num_patches_per_side` grid (via `bucketize`) and flattens to 1-D embedding
    indices, concatenated across all images. Used by NaViT-style packers (e.g. MiniCPM-V).

    Args:
        target_sizes: `(num_images, 2)` int â€” `(h, w)` per image.
        num_patches_per_side: side length of the learned 2-D position-embedding grid.
        kwargs: optional caller kwargs â€” if it contains `"position_ids"` it is popped and returned.

    Returns:
        `position_ids`: `(sum(h_i * w_i),)` long â€” flat indices into a `num_patches_per_side**2` table.
    Nr   r   g      ð?r   T)Úright)
r   r   r   r)   r'   r"   Ú	bucketizer-   r,   r0   )Útarget_sizesÚnum_patches_per_sider   Úpos_idsr   Ú
boundariesÚpos_ids_listÚheightÚwidthÚh_coordsÚw_coordsÚbucket_hÚbucket_ws                r   Úget_vision_nearest_position_idsr‡   ì   s  € ð$ Ð¨&¯*©*°^ÀTÓ*JÐJ˜wÐWØˆØ× Ñ €FÜ—‘˜aÐ"6Ñ6¸¸QÐAUÑ=UÐ^dÔe€JØ€LØ%×,Ñ,Ó.ò ]‰ˆ�Ü˜F›¤S¨£Z�ˆÜ—<‘< ¨vÔ6¸Ñ?ˆÜ—<‘< ¨fÔ5¸Ñ=ˆÜ—?‘? 8¨Z¸tÔDˆÜ—?‘? 8¨Z¸tÔDˆØ×Ñ˜X¢a¨ gÑ.Ð1EÑEÈÑP×YÑYÓ[Õ\ð]ô �9‰9�\Ó"Ð"r   c                ó¸   — |�|j                  dd«      x}�|S |\  }}t        | d   j                  «       «      |z  t        | d   j                  «       «      |z  fS )uÔ  Get post-window-merge `(merged_h, merged_w)` Python ints, or pop from `kwargs` if precomputed.

    `.view()` needs Python ints, but `target_sizes[0].item()` is non-traceable. Callers must pop
    the precomputed value from `kwargs` when running under `torch.export`. Assumes uniform
    `target_sizes` across the batch (standard NaViT preprocessing output).

    Args:
        target_sizes: `(num_images, 2)` int â€” `(h, w)` per image.
        window_kernel_size: `(window_h, window_w)` window-attention kernel.
        kwargs: optional caller kwargs â€” if it contains `"merged_shape"` it is popped and returned.

    Returns:
        `(merged_h, merged_w)`: per-image grid size after window merging, as Python ints.
    NÚmerged_shape)r   r   )r   r   )r   r"   Úitem)r|   Úwindow_kernel_sizer   ÚmergedÚwindow_hÚwindow_ws         r   Úget_vision_merged_shaper�     sj   € ð" Ð¨¯©°NÀDÓ)IÐI˜vÐVØˆØ+Ñ€HˆhÜˆ|˜DÑ!×&Ñ&Ó(Ó)¨XÑ5´s¸<ÈÑ;M×;RÑ;RÓ;TÓ7UÐYaÑ7aÐaÐar   )N)r   útorch.Tensorr   údict | NoneÚreturnr�   )FN)
r   r�   r1   zint | torch.Tensorr2   Úboolr   r‘   r’   r�   )r   r�   r1   r"   rF   r"   rG   r"   r   r‘   r’   ú!tuple[torch.Tensor, torch.Tensor])
r   r�   rb   r"   r1   r"   r   r‘   r’   r”   )r|   r�   r}   r"   r   r‘   r’   r�   )r|   r�   r‹   útuple[int, int]r   r‘   r’   r•   )Ú__doc__Ú
__future__r   r   Útorch.nn.functionalÚnnÚ
functionalr   r   r;   rY   rx   r‡   r�   © r   r   ú<module>rœ      s9  ðñõ #ã ß Ð ô.ð* #Øð	.*Øð.*à*ð.*ð ð.*ð ð	.*ð
 ó.*ðl ð:+Øð:+àð:+ð ð:+ð ð	:+ð
 ð:+ð 'ó:+ðB ð	F.ØðF.àðF.ð ðF.ð ð	F.ð
 'óF.ðT RVð#Øð#Ø69ð#ØCNð#àó#ðD \`ðbØðbØ4CðbØMXðbàôbr   