
    9i`                         S SK r S SKJr  S SKrS SKJrJ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Jr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   S SK!J"r"J#r#  S SK$J%r%  S SK&J'r'  S SK(J)r)J*r*J+r+  S SK,J-r-J.r.J/r/  S SK0J1r1J2r2  S SK3J4r4J5r5  S SK6J7r7  S SK8J9r9  SSK:J;r;  SSK<J=r=J>r>  \5" 5       (       a  S SK?r?\4" 5       (       a   \S   r@\\A\B\SS4   rC\\A\S4   rD\7" 5       rE " S S\5      rF " S S\F5      rGS  rHg)!    N)ABCabstractmethod)partial)Pool)Lock)AnyDict	GeneratorListMappingOptionalUnion)version)Model)	MsDataset)TASK_OUTPUTSModelOutputBase)TASK_INPUTScheck_input_type)Preprocessor)Config)
FrameworksInvoke	ModelFile)create_devicedevice_placementverify_device)read_configsnapshot_download)is_tf_availableis_torch_available)
get_logger)compile_model   )check_model_from_owner_group   )is_modelis_official_hub_path)ztorch.Tensorz	tf.TensorzImage.Imageznumpy.ndarrayztorch.nn.Modulec            
          \ rS rSrSrS rS\\   4S jr      S!S\	S\
\\\   4   S	\
\\\   4   S
\	4S jjr  S"S\\	   S\\	   4S jjrS rS\	4S jrS\
\\\   4   S\
\\	\4   \4   4S jrS rS\4S jrS rS\S\\	\4   4S jrS rS\\   S\\	\4   4S jrS rS rS\S\\	\4   4S jrS\\	\4   S\\	\4   4S jrS\\	\4   S\\	\4   4S jr S r!g)#Pipeline,   zPipeline base.
    c                    U R                   (       a  SUS'   [        U[        5      (       a  [        R	                  SU 35        [        U[        5      (       ay  [        U5      (       ai  [        R	                  SU S35        [        U5      (       a>  [        R                  " U4U R                  S[        R                  U R                  S.UD6$ U$ U$ )NTtrust_remote_codezinitiate model from zinitiate model from location .)devicemodel_prefetched
invoked_by
device_map)r-   
isinstancestrloggerinfor(   r'   r   from_pretraineddevice_namer   PIPELINEr2   )selfmodelkwargss      Y/var/www/html/land-doc-ocr/venv/lib/python3.13/site-packages/modelscope/pipelines/base.pyinitiate_single_modelPipeline.initiate_single_model0   s    !!*.F&'eS!!KK.ug67eS!!&:5&A&AKK7wa@A &e__ ((''!%!????  8 388 L    input_modelsc                 \    / nU H#  nUR                  U R                  U5      5        M%     U$ N)appendr>   )r:   rA   modelsr;   s       r=   initiate_multiple_models!Pipeline.initiate_multiple_modelsB   s-    !EMM$44U;< "r@   Nconfig_filer;   preprocessorr/   c                    Ub  US:X  d   S5       eX`l         [        U5        X@l        UR                  SS5      U l        [        U[        5      (       d+  U R                  " U40 UD6U l        U R                  /U l	        OSU l        U R                  U5      U l	        [        U R                  5      S:  U l        Ub;  [        R                  " U5      U l        [         R"                  R%                  U5      nOcU R                  (       dR  [        U R                  [&        5      (       a  U R                  nOU R                  R(                  n[+        U5      U l        Uc-  U R                  (       d  [,        R.                  " W5      U l        OX0l        U R                  (       d%  U R                  (       a*  U R                  S   (       a  U R3                  5       U l        OSU l        U R4                  [6        R8                  :X  a  [;        U R                  5      U l        SU l        [A        5       U l!        XPl"        UR                  SS5      U l#        UR                  S	0 5      U l$        g)
a  Base class for pipeline.

If config_file is provided, model and preprocessor will be
instantiated from corresponding config. Otherwise, model
and preprocessor will be constructed separately.

Args:
    config_file(str, optional): Filepath to configuration file.
    model: (list of) Model name or model object
    preprocessor: (list of) Preprocessor object
    device (str): device str, should be either cpu, cuda, gpu, gpu:X or cuda:X
    auto_collate (bool): automatically to convert data to tensor or not.
    compile (bool, optional): Compile the model with torch 2.0, default False
    compile_options (dict, optional): The compile options if compile=True,
        default None to use the default params of 'TorchModel.compile'.
Ngpuz;`device` and `device_map` cannot be input at the same time!r-   Fr&   r   compilecompile_options)%r2   r   r8   getr-   r3   r   r>   r;   rE   rF   lenhas_multiple_modelsr   	from_filecfgospathdirnamer4   	model_dirr   r   r7   rI   _get_framework	frameworkr   torchr   r/   _model_preparer   _model_prepare_lock_auto_collate_compile_compile_options)	r:   rH   r;   rI   r/   auto_collater2   r<   rV   s	            r=   __init__Pipeline.__init__H   s   0 !U?a$aa?$f!!',?!G%&&33EDVDDJ::,DKDJ77>DK#&t{{#3a#7 "''4DH4I))$**c** JJ	 JJ00	"9-DH(@(@ , < <Y GD ,::$22t{{1~!002DN!DN>>Z---'(8(89DK##'6 )

9e4 &

+<b Ar@   info_strrV   c                 h    U=(       d    Sn[        US9(       d  U R                  (       d   U5       egg)a  Check trust_remote_code if the pipeline needs to import extra libs

Args:
    info_str(str): The info showed to user if trust_remote_code is `False`.
    model_dir(`Optional[str]`): The local model directory. If is a trusted model, check remote code will pass.
zThis pipeline requires `trust_remote_code` to be `True` because it needs to import extra libs or execute the code in the model repo, setting this to true means you trust the files in it.)rV   N)r%   r-   )r:   rb   rV   s      r=   check_trust_remote_code Pipeline.check_trust_remote_code   s:      0/ 	 ,i@))383) Ar@   c                 f  ^  T R                   R                  SS9  U 4S jnT R                  (       d  T R                  [        R
                  :X  a  T R                  (       ac  T R                   H  nU" U5        M     T R                  (       a6  T R                   Vs/ s H  n[        U40 T R                  D6PM     snT l        OHU" T R                  5        T R                  (       a%  [        T R                  40 T R                  D6T l        ST l        T R                   R                  5         gs  snf )zPPlace model on certain device for pytorch models before first inference
        iX  )timeoutc                 d  > [        U [        R                  R                  5      (       d  [	        U S5      (       a  U R
                  n [        U [        R                  R                  5      (       d  g U R                  5         SSKJn  U" U 5      (       a  U R                  TR                  5        g g )Nr;   r   )is_on_same_device)r3   rY   nnModulehasattrr;   evalmodelscope.utils.torch_utilsri   tor/   )r;   ri   r:   s     r=   _prepare_single/Pipeline.prepare_model.<locals>._prepare_single   sv    eUXX__55'7;$ ;$eUXX__55JJLF ''% (r@   TN)r[   acquirerZ   rX   r   rY   rP   rE   r]   r#   r^   r;   release)r:   rp   ms   `  r=   prepare_modelPipeline.prepare_model   s     	  (((5		& ""~~!1!11++![['* )}} &*[['%0 *!Et/D/DE%0'
 $DJJ/}}%24:: &L595J5J&L
"&D  ((*'s    D.returnc                   ^ / mU R                    H}  n[        U[        5      (       a  UnOUR                  n[        R
                  " U[        R                  5      n[        R                  " U5      nTR                  UR                  5        M     [        U4S jT 5       5      (       d  [        R                  ST 35        g TS   $ )Nc              3   2   >#    U  H  oTS    :H  v   M     g7f)r   N ).0x
frameworkss     r=   	<genexpr>*Pipeline._get_framework.<locals>.<genexpr>   s     :z!
1%zs   z:got multiple models, but they are in different frameworks r   )rE   r3   r4   rV   ospjoinr   CONFIGURATIONr   rQ   rD   rX   allr5   warning)r:   rt   rV   cfg_filerR   r}   s        @r=   rW   Pipeline._get_framework   s    
A!S!!	KK	xx	9+B+BCH""8,Ccmm,  :z:::NNLZLY !}r@   inputc                    U R                   (       d%  U R                  (       a5  U R                  S   (       a!  U R                  (       d  U R	                  5         UR                  SS 5      nU R                  " S
0 UD6u  pVnXSS'   XcS'   XsS'   S[        U 5      R                  ;   a  [        U[        5      (       a	  SU0nSUS	'   [        U[        5      (       aK  Uc2  / nU H(  n	UR                  U R                  " U	/UQ70 UD65        M*     U$ U R                  " X40 UD6n U$ [        U[        5      (       a  U R                  " U/UQ70 UD6$ U R                  " U/UQ70 UD6nU$ )Nr   
batch_sizepreprocess_paramsforward_paramspostprocess_paramsLLMPipelinemessagesT
is_messagerz   )r;   rP   rE   rZ   ru   pop_sanitize_parameterstype__name__r3   listrD   _process_single_process_batchr   _process_iterator)
r:   r   argsr<   r   r   r   r   outputeles
             r=   __call__Pipeline.__call__   sg   
 JJ433A&&""$ ZZd3
@D@Y@Y AA=+=&7"##1 '9#$ DJ///Jud4K4K'E#'F< eT""! CMM$"6"6s"LT"LV"LM !  ,,UI&I  y))))%A$A&AA ))%A$A&AFr@   c                     0 0 U4$ )a  
this method should sanitize the keyword args to preprocessor params,
forward params and postprocess params on '__call__' or '_process_single' method
considered to be a normal classmethod with default implementation / output

Default Returns:
    Dict[str, str]:  preprocess_params = {}
    Dict[str, str]:  forward_params = {}
    Dict[str, str]:  postprocess_params = pipeline_parameters
rz   )r:   pipeline_parameterss     r=   r   Pipeline._sanitize_parameters   s     2***r@   c              /   N   #    U H  nU R                   " U/UQ70 UD6v   M     g 7frC   )r   )r:   r   r   r<   r   s        r=   r   Pipeline._process_iterator  s*     C&&s<T<V<< s   #%c                 ,    [        XR                  5      $ rC   )
collate_fnr/   )r:   datas     r=   _collate_fnPipeline._collate_fn  s    $,,r@   c                    UR                  S0 5      nUR                  S0 5      nUR                  S0 5      nU R                  U5        U R                  " U40 UD6n[        U R                  U R
                  5         U R                  [        R                  :X  aT  [        R                  " 5          U R                  (       a  U R                  U5      nU R                  " U40 UD6nS S S 5        OU R                  " U40 UD6nS S S 5        U R                  " U40 UD6nU R                  U5        U$ ! , (       d  f       N<= f! , (       d  f       NE= f)Nr   r   r   )rN   _check_input
preprocessr   rX   r8   r   rY   no_gradr\   r   forwardpostprocess_check_output)r:   r   r   r<   r   r   r   outs           r=   r   Pipeline._process_single  s   "JJ':B?$4b9#ZZ(<bA% ooe9'89dnnd.>.>?~~!1!11]]_))"..s3,,s=n=C %_
 ll39.9 @ s9&893
 %_ @?s$   ;4E /6D/%E /
D=	9E  
Ec                 J   0 nU HC  nUR                  5        H,  u  pEUR                  U/ 5      nUR                  U5        XbU'   M.     ME     UR                  5        HC  n[	        X$   S   [
        R                  5      (       d  M)  [
        R                  " X$   5      X$'   ME     U$ )Nr   )itemsrN   rD   keysr3   rY   Tensorcat)r:   	data_list
batch_datasample_preprocessedkv
value_lists          r=   _batchPipeline._batch"  s    
#,+113'^^Ar2
!!!$ *1 4 $-
 "A*-*ELL99 %		*- 8
 # r@   c           	        ^ UR                  S5      nUR                  S5      nUR                  S5      n/ n[        S[        U5      U5       GH  n[        X-   [        U5      5      n	X-
  n
XU	  Vs/ s H  oR                  " U40 UD6PM     nn[        U R                  U R                  5         U R                  [        R                  :X  ae  [        R                  " 5          U R                  U5      nU R                  (       a  U R                  U5      nU R                  " U40 UD6nS S S 5        O$U R                  U5      nU R                  " U40 UD6nS S S 5        [        U
5       H  m0 nWR                  5        Hy  u  pUc  M
  [!        U["        [$        45      (       aJ  [!        US   [        R&                  5      (       a  [)        U5      " U4S jU 5       5      X'   Mf  UT   X'   Mo  UTTS-    X'   M{     U R*                  " U40 UD6nU R-                  U5        UR/                  U5        M     GM     U$ s  snf ! , (       d  f       N= f! , (       d  f       GN= f)Nr   r   r   r   c              3   4   >#    U  H  nUTTS -    v   M     g7f)r&   Nrz   )r{   e	batch_idxs     r=   r~   *Pipeline._process_batch.<locals>.<genexpr>O  s#      76-4 %&i	A$>-4s   r&   )rN   rangerO   minr   r   rX   r8   r   rY   r   r   r\   r   r   r   r3   tupler   r   r   r   r   rD   )r:   r   r   r<   r   r   r   output_listiendreal_batch_sizepreprocessed_listbatched_outr   r   elementr   s                   @r=   r   Pipeline._process_batch.  s#   "JJ':;$45#ZZ(<= q#e*j1Aanc%j1C!gOAF!AMA7%67  ! "$..$2B2BC>>Z%5%55&*kk2C&D--*.*:*:;*GK&*ll; 'E5C'E	 ) #'++.?"@K"&,,{"Mn"MK D #?3	"-"3"3"5JA*%gt}==)'!*ellCC)-g 76-476 *6
 *1);%,Yy1}%ECF #6 &&sA.@A""3'""3'! 4' 2J E! ) DCs+   2H=04I$AI+-I
II
I"	c                    U R                   nU[        ;   Gax  [        U   n[        U[        5      (       a  S nU HU  n[        U[        [
        45      (       a  [        U5      [        U5      :X  a  Un  OM<  [        U[        5      (       d  MS  Un  O   Uc  SnU H
  nXe S3-  nM     [        U5      eUn[        U[        5      (       a  [        X15        g [        U[
        5      (       a<  [        U[
        5      (       d   S5       e[        X15       H  u  pW[        XW5        M     g [        U[        5      (       aF  UR                  5        H1  n[        U[        5      (       d  M  X;   d  M!  [        X8   X   5        M3     g [        SU 35      e[        U SS5      (       d!  [        R                  SU S35        S	U l        g g )
NzDinput data format for current pipeline should be one of following: 

zinput should be a tuplezinvalid input_type definition _input_has_warnedFtask z input definition is missingT)	group_keyr   r3   r   dictr   r   r4   
ValueErrorr   zipr   getattrr5   r   r   )	r:   r   	task_name
input_typematched_typeterr_msg	input_eler   s	            r=   r   Pipeline._check_input]  s   NN	#$Y/J *d++##A!%$777d5k1+,L! 2 $As++'( $  'eG'S8+ ($W--!-J*c** 3J..!%//J1JJ/$'
$:LA$Q2 %;J--#*A!%..1:(A +
 !#A*!NOO2E::NNU9+-IJK%)D" ;r@   c                    U R                   nU[        ;  a3  [        U SS5      (       d   [        R	                  SU S35        SU l        g [        U   n/ n[        U[        [        45      (       a  UR                  5       OUnU H8  n[        U[        [        45      (       d  M   XQ;  d  M'  UR                  U5        M:     [        U5      S:  a  [        SU SU S	35      eg )
N_output_has_warnedFr   z output keys are missingTr   zexpected output keys are z, those z are missing)r   r   r   r5   r   r   r3   r   r   r   rD   rO   r   )r:   r   r   output_keysmissing_keysr   s         r=   r   Pipeline._check_output  s     NN	L(4!5u==yk1IJK*.'"9- *5,0/+B!D !D

IN 	A!dO455!.##A&  |q 8 F&&2^<A B B !r@   inputsc                     U R                   c   S5       e[        U R                   [        5      (       a   S5       eU R                   " U40 UD6$ )z[Provide default implementation based on preprocess_cfg and user can reimplement it
        z'preprocess method should be implementedzEdefault implementation does not support using multiple preprocessors.)rI   r3   r   )r:   r   r   s      r=   r   Pipeline.preprocess  sX       ,W.WW,d//66 	TS	T6  =+<==r@   c                     U R                   c   S5       eU R                  (       a   S5       eU R                   " U40 UD6$ )zTProvide default implementation using self.model and user can reimplement it
        z$forward method should be implementedzFdefault implementation does not support multiple models in a pipeline.)r;   rP   )r:   r   r   s      r=   r   Pipeline.forward  sC     zz%M'MM%++u-uu+zz&3N33r@   c                     [        S5      e)a"  If current pipeline support model reuse, common postprocess
    code should be write here.

Args:
    inputs:  input data
    post_params:   post process parameters

Return:
    dict of results:  a dict containing outputs of model, each
        output should have the standard output name.
r   )NotImplementedError)r:   r   post_paramss      r=   r   Pipeline.postprocess  s     "-00r@   )r\   r]   r^   r   rZ   r[   r   rR   r/   r2   r8   rX   rP   r;   rE   rI   r-   )NNNrK   TN)NN)"r   
__module____qualname____firstlineno____doc__r>   r   
InputModelrF   r4   r   r   r`   r   rd   ru   rW   Inputr	   r   r
   r   r   r   r   r   r   r   r   r   r   r   r   __static_attributes__rz   r@   r=   r*   r*   ,   s   $T*5E  %)>BIM$" BB!BBj$z*::;BB  %\43E%EFBB 	BBJ ;?;?4*23-4+3C=4 !+F $'eE4;$67 '#DcNI$=>'R+=u =-U S#X (
-DK -$(cN-^(*TB(> >S#X >4d38n 4%)#s(^41$sCx. 1&*38n1r@   r*   c                       \ rS rSrSr   SS\S\\\\   4   4S jjr	S r
S r\S	 5       rS
\\\4   S\\\4   4S jr\S 5       rS\S\4S jrSrg)DistributedPipelinei  a  This pipeline is used to load multi gpu models.

What will this class do:
1. Read the global config from the configuration.json
2. Set the multiprocessing method to spawn
3. Open a multiprocessing pool of the world_size to instantiate model pieces.
4. Set the master port and ip
5. Call _instantiate_one to instantiate one model piece,
This method should be implemented by the derived class.
6. After the forward method is called, do preprocess in main process and
call _forward_one to collect results, and do post process in main process.

NOTE: _instantiate_one and _forward_one are class methods, any derived class should implement them and
store the model handler in the class field.
Nr;   rI   c                 P   X l         SU l        [        5       U l        X0l        [
        R                  R                  U5      (       a  Xl        O[        U5      U l        [        U R                  5      U l        U R                  U R                  5      U l        S U l        SU l        [!        U R                  5      U l        SU l        U R                  R&                  U l        [(        R*                  R-                  SSS9  [/        [1        U R                  5      5      n[3        U R                  5      U l        SU;  a  SUS'   SU;   a  [5        US   5      O[6        R8                  " S	S
5      nSSKJnJn  U" U5      (       d  U" 5       n[A        U5      US'   US   [
        RB                  S'   US   [
        RB                  S'   U R                  RE                  [G        U RH                  RJ                  4SU R                  0U R                  RL                  DUD6U5        / U l'        g )NFcpuspawnT)force	master_ipz	127.0.0.1master_porti<s  iL  r   )_find_free_port_is_free_portMASTER_ADDRMASTER_PORTrV   )(rI   rZ   r   r[   r\   rS   rT   existsrV   r   r   rR   _get_world_size
world_size
model_poolr8   r   r/   rP   rX   rY   multiprocessingset_start_methodr   r   r   intrandomrandintrn   r   r   r4   environmapr   	__class___instantiate_oner;   rE   )	r:   r;   rI   r_   r<   ranksr   r   r   s	            r=   r`   DistributedPipeline.__init__  s    )##'6 )77>>%  "N.u5DNt~~...txx8 #D$4$45#( ++..wd.CU4??+,t/f$"-F;,6 &/ <BNN#U=, 	 	P[)))+K #K 0}$*;$7

=!$*=$9

=!//.. ((.. 	 !	" r@   c                     [        U S5      (       a*  U R                  b   U R                  R                  5         g g g ! [         a     g f = f)Nr  )rl   r  	terminateAttributeError)r:   s    r=   __del__DistributedPipeline.__del__  sJ    4&&4??+F))+ ,G& " s   = 
A
	A
c                 L    U R                   R                  5       nUS	 US	 US	 U$ )Nr  rI   r[   )__dict__copy)r:   	self_dicts     r=   __getstate__ DistributedPipeline.__getstate__  s3    MM&&(	l#n%+,r@   c                     g)zInstantiate one model piece.

Args:
    rank: The model rank.
    model_dir: The model_dir in the node.
    kwargs: Any extra args.

Returns:
    None. The model handler should be kept in the class field.
Nrz   )clsrankrV   r<   s       r=   r
  $DistributedPipeline._instantiate_one       	r@   r   rw   c                     UUS.nU R                   R                  U R                  R                  U/U R                  -  5      nUS   $ )N)r   r   r   )r  r  r	  _forward_oner   )r:   r   r   ress       r=   r   DistributedPipeline.forward  sJ     ,
 oo!!$.."="=#)(T__"<>1vr@   c                     g)zForward the inputs to one model piece.

Use the model handler kept in the class field to forward.

Args:
    inputs: The inputs after the preprocessing.

Returns:
    The forward results.
Nrz   )r  r   s     r=   r   DistributedPipeline._forward_one#  r  r@   rR   c                 P    UR                  S5      nUc  UR                  S5      $ U$ )Nzmegatron.world_sizezmodel.world_size)safe_get)r:   rR   m_world_sizes      r=   r   #DistributedPipeline._get_world_size1  s-    ||$9:<< 233r@   )r\   rZ   r[   rR   r/   r8   rX   rP   rV   r  rE   rI   r   )NNT)r   r   r   r   r   r4   r   r   r   r`   r  r  classmethodr
  r	   r   r   r  r   r  r   r   rz   r@   r=   r   r     s    " #IM"//$\43E%EF/b  d38n %)#s(^  6 c r@   r   c                 $  ^ SSK Jn  S n[        U [        5      (       d  [        U [        5      (       aF  [        U 5      " U R                  5        VVs0 s H  u  pEXDS:w  a  [        UT5      OU_M     snn5      $ [        U [        [        45      (       au  S[        U 5      :X  a  [        R                  " / 5      $ [        U S   [        [        45      (       a  U" U 5      R                  T5      $ [        U 5      " U4S jU  5       5      $ [        U [         R"                  5      (       aI  U R$                  R
                  [         R&                  L a  U $ [        [        R(                  " U 5      T5      $ [        U [        R                  5      (       a  U R                  T5      $ [        U [*        [,        [        [        [.        [        S5      45      (       a  U $ U" U 5      S:X  a  U $ U" U 5      S:X  a  U $ [1        S	[        U 5       35      es  snnf )
a  Prepare the input just before the forward function.
This method will move the tensors to the right device.
Usually this method does not need to be overridden.

Args:
    data: The data out of the dataloader.
    device: The device to move data to.

Returns: The processed data.

r   )default_collatec                 .    U R                   R                  $ rC   )r	  r   )objs    r=   get_class_name"collate_fn.<locals>.get_class_nameF  s    }}%%%r@   	img_metasc              3   <   >#    U  H  n[        UT5      v   M     g 7frC   )r   )r{   r   r/   s     r=   r~   collate_fn.<locals>.<genexpr>U  s     BTjF33Ts   NInputFeaturesDataContainerzUnsupported data type )torch.utils.data.dataloaderr)  r3   r   r   r   r   r   r   r   rO   rY   r   r  floatro   npndarraydtypestr_
from_numpybytesr4   boolr   )r   r/   r)  r,  r   r   s    `    r=   r   r   8  s    <& $D'!:!:Dz


$ [(8z!V$a?$
  	 
D5$-	(	(D	><<##d1gU|,,"4(++F33:BTBBB	D"**	%	%::??bgg%Ke..t4f==	D%,,	'	'wwv	D5#sE4dD	E	E			0			01$t*>??7
s    H
)IrS   os.pathrT   r   r  abcr   r   	functoolsr   r  r   	threadingr   typingr   r	   r
   r   r   r   r   numpyr5  	packagingr   modelscope.models.baser   modelscope.msdatasetsr   modelscope.outputsr   r   modelscope.pipeline_inputsr   r   modelscope.preprocessorsr   modelscope.utils.configr   modelscope.utils.constantr   r   r   modelscope.utils.devicer   r   r   modelscope.utils.hubr   r   modelscope.utils.import_utilsr    r!   modelscope.utils.loggerr"   rn   r#   utils.automodel_utilsr%   utilr'   r(   rY   r   r4   r   r   r   r5   r*   r   r   rz   r@   r=   <module>rP     s    
   #     G G G   ( + < D 1 * C C4 4 ? M . 6 @ 0	*	+c5)]OCD3001
	L1s L1^z( zz.@r@   