
    9iR+                         S SK r S SKrS SKrS SKrS SKJr  S SKrS SKJr  S SK	J	r	  S SK
Jr  S SKJrJrJrJrJr     SS jr     SS jrS	 rS
 rSS jrSS jrS rg)    N)Mapping)distributed)tqdm)	to_device)	broadcastget_dist_infois_dist	is_mastermake_tmp_dirc           
         UR                   nSnUc   [        U5      nSn
OSnUnSn
[        XS9 n[        U5       H  u  p[        X5      n[        XX45        U(       a  SnOY[        U[        5      (       a9  S	U;   a  US	   nO8 [        [        [        UR                  5       5      5      5      nO[        U5      n[!        U5       H  nUR#                  5         M     U(       d  M  US-   U:  d  M    O   SSS5        [%        U5      $ ! [         a&  n	[        R                  " U	5        [        S5      eSn	A	ff = f! [         a    UR                  n Nf = f! , (       d  f       Nh= f)
a  Test model in EpochBasedTrainer with a single gpu.

Args:
    trainer (modelscope.trainers.EpochBasedTrainer): Trainer to be tested.
    data_loader (nn.Dataloader): Pytorch data loader.
    device (str | torch.device): The target device for the data.
    metric_classes (List): List of Metric class that uses to collect metrics.
    vis_closure (Callable): Collect data for TensorboardHook.
    data_loader_iters (int): Used when dataset has no attribute __len__ or only load part of dataset.

Returns:
    list: The prediction results.
FNzVPlease implement ``__len__`` method for your dataset, or provide ``data_loader_iters``zTotal test samplesTzTest iterationstotaldesc   
nsentences)datasetlen	Exceptionloggingerror
ValueErrorr   	enumerater   evaluate_batch
isinstancer   nextitervalues
batch_sizerangeupdateget_metric_values)trainerdata_loaderdevicemetric_classesvis_closuredata_loader_itersr   progress_with_itersdata_lener   pbaridatar   _s                   c/var/www/html/land-doc-ocr/venv/lib/python3.13/site-packages/modelscope/trainers/utils/inference.pysingle_gpu_testr0      sV   & !!G 	7|H $"$ 	H	(D -GAT*D7.F"
dG,,#t+%),%7
@),T$t{{}2E-F)GJ "%TJ:& ' #"A(':+ . 
)0 ^,,G  	MM!h 	2  ) @)4)?)?J@ 
)	(sS   D AE+D;/3E&E1E
D8!D33D8;EEEE
E%c           
         UR                   n[        U R                  5      u  pSnUc   [        U5      nUnSnO
SnSnXz-  nSnSn[        XS9 n[        U5       GH\  u  nn[        UU5      n[        U UX45        [        U[        5      (       a8  S	U;   a  US	   nO7[        [        [        UR!                  5       5      5      5      nO[        U5      nUX-  S
-
  :  ax  ["        R$                  " U/5      R'                  U R(                  R*                  5      n[,        R.                  " U[,        R0                  R2                  S9  UR5                  5       nOUU
-  nU(       a  U
nOUnUU-  nU	S:X  a0  UU:  a  UUU-
  -
  n[7        U5       H  nUR9                  5         M     U(       d  GMQ  US
-   U:  d  GM]    O   SSS5        U(       a  [;        UU R                  5      nO7Uc
  [=        5       n[?        X0[@        RB                  RE                  US5      5      n[G        U5      n[I        U5      $ ! [         a&  n[
        R                  " U5        [        S5      eSnAff = f! , (       d  f       N= f)a  Test model in EpochBasedTrainer with multiple gpus.

This method tests model with multiple gpus and collects the results
under two different modes: gpu and cpu modes. By setting
``gpu_collect=True``, it encodes results to gpu tensors and use gpu
communication for results collection. On cpu mode it saves the results on
different gpus to ``tmpdir`` and collects them by the rank 0 worker.

Args:
    trainer (modelscope.trainers.EpochBasedTrainer): Trainer to be tested.
    data_loader (nn.Dataloader): Pytorch data loader.
    device: (str | torch.device): The target device for the data.
    tmpdir (str): Path of directory to save the temporary results from
        different gpus under cpu mode.
    gpu_collect (bool): Option to use either gpu or cpu to collect results.
    data_loader_iters_per_gpu (int): Used when dataset has no attribute __len__ or only load part of dataset.
Returns:
    list: The prediction results.
FNz^Please implement ``__len__`` method for your dataset, or provide ``data_loader_iters_per_gpu``z"Total test samples with multi gpusr   Tz%Total test iterations with multi gpusr   r   r   )opmetrics)%r   r   dp_groupr   r   r   r   r   r   r   r   r   r   r   r   r   r   torch
LongTensortomodelr$   dist
all_reduce	reduce_opSUMitemr   r    collect_results_gpur   collect_results_cpuospathjoinmerge_metricsr!   )r"   r#   r$   r%   r&   tmpdirgpu_collectdata_loader_iters_per_gpur   rank
world_sizer(   r)   total_samplesr*   r   countr+   r,   r-   r   iter_cnt_allr.   metric_classes_lists                           r/   multi_gpu_testrM   P   sN   6 !!G$W%5%56D (	7|H$M 4",96E	H	(D -GAtT6*D7D.F$((4'!%l!3J!$T$t{{}*=%>!?J Y
X+q00 % 0 0* 24 !557R8L8L5M $..2D2DE - 2 2 4 *Z 7"),%qy8##+u|/C#DL|,AKKM - #"A(':A . 
)H 1.292B2BD >!^F1RWW\\&)%DF ##67N^,,y  	MM!p 	 
)	(s0   H/ EI",I"8I"/
I9!II"
I0c                 x    U R                  U5      nUb  U H  nUR                  XA5        M     Ub	  U" U5        g g N)evaluation_stepadd)r"   r-   r%   r&   batch_result
metric_clss         r/   r   r      sC    **40L!(JNN<. ) L!     c                     0 n[        5       (       a(  U  H"  nUR                  UR                  5       5        M$     [        5       (       a  [	        US5      nU$ )Nr   )r
   r    evaluater	   r   )r%   metric_valuesrS   s      r/   r!   r!      sH    M{{(J  !4!4!67 )yy!-3rT   c                    [        UR                  5      u  p4Uc
  [        5       n[        R                  R                  U5      (       d  [        R                  " USS9  [        R                  " 5         UR                  5       (       a  [        UR                  5      (       a|  UR                  5       (       a  [        UR                  5      (       aM  [        [        R                  R                  USU S35      S5       n[         R"                  " X5        SSS5        [        R                  " 5         [        5       (       d  g/ n[%        U5       Hl  n[        R                  R                  USU S35      n[        US5       n[         R&                  " U5      n	SSS5        W	(       d  M[  UR)                  U	5        Mn     [*        R,                  " U5        U$ ! , (       d  f       N= f! , (       d  f       NU= f)a  Collect results under cpu mode.

On cpu mode, this function will save the results on different gpus to
``tmpdir`` and collect them by the rank 0 worker.

Args:
    result_part (list): Result list containing result parts
        to be collected.
    trainer(`EpochBasedTrainer`): The trainer instance to get the parallel groups.
    tmpdir (str | None): temporal directory for collected results to
        store. If set to None, it will create a random temporal directory
        for it.

Returns:
    list: The collected results.
NT)exist_okpart_z.pklwbrb)r   r4   r   r@   rA   existsmakedirsr9   barrieris_tp_group_availabler
   tp_groupis_pp_group_availablepp_groupopenrB   pickledumpr   loadappendshutilrmtree)
result_partr"   rD   rG   rH   f	part_listr,   	part_filepart_results
             r/   r?   r?      sb   " %W%5%56D~77>>&!!
FT*LLN ))++y9I9I/J/J2244	'BRBR8S8S"'',,vtfD'9:DAQKK' BLLN;; 	z"AVuQCt_=Ii&!$kk!n ' {  - # 	f) BA '&s   ?GG)
G&)
G7	c                    [        U5      u  p#[        R                  " [        [        R
                  " U 5      5      [        R                  SS9n[        R                  " UR                  SS9n[        U5       Vs/ s H  o%R                  5       PM     nn[        R                  " XeU5        [        R                  " U5      R                  5       n[        R                  " U[        R                  SS9nXHSUS   & [        U5       Vs/ s H  o$R                  U5      PM     n	n[        R                  " XU5        [        5       (       ax  / n
[!        X5       He  u  p[        R"                  " USUS    R%                  5       R'                  5       R)                  5       5      nU(       d  MT  U
R+                  U5        Mg     U
$ gs  snf s  snf )av  Collect results under gpu mode.

On gpu mode, this function will encode results to gpu tensors and use gpu
communication for results collection.

Args:
    result_part (list): Result list containing result parts
        to be collected.
    dp_group(`ProcessGroup` or None): The data parallel group, default None for global group.

Returns:
    list: The collected results.
cuda)dtyper$   )r$   Nr   )r   r5   tensor	bytearrayre   dumpsuint8shaper   cloner9   
all_gathermaxzeros	new_zerosr
   ziploadscpunumpytobytesrh   )rk   r4   r.   rH   part_tensorshape_tensor
shape_list	shape_max	part_sendpart_recv_listrm   recvrw   ro   s                 r/   r>   r>      sv    "(+MA ,,&,,{+,EKKPK << 1 1&AL05j0AB0A1$$&0AJBOOJh7Z(,,.IIU[[HI"-|A27
2C2CQi(2C   	OONx8{{	~:KD ,,tIU1X':':'<'B'B'D'L'L'NOK {  - ;   Cs   ;G	G	c                 z    U c  g U S   nU SS   H(  n[        X5       H  u  p4UR                  U5        M     M*     U$ )Nr   r   )r}   merge)rL   metric_classes_0metric_classes_icls_0cls_is        r/   rC   rC   '  sO    "*1-/3 0CLEKK D 4 rT   )NNN)NNNFNrO   )r   r@   re   ri   collections.abcr   r5   r   r9   r   modelscope.utils.data_utilsr   modelscope.utils.torch_utilsr   r   r	   r
   r   r0   rM   r   r!   r?   r>   rC    rT   r/   <module>r      sr     	   #  %  1C C $( $&*;-B #'#$-1_-D	"/d*ZrT   