o
    ٷiP                     @   s4  d dl Z d dlZd dlmZ d dlmZmZmZ d dlm	Z	 d dl
mZmZmZ d dlmZ d dlmZ d dlmZmZ d d	lmZ d d
lmZ d dlmZ e	ejjjZeeZdede e!ef de!de!ddf
ddZ"de!de!dB fddZ#de eB de fddZ$dedefddZ%de!de!fddZ&d<de!de dB de'fddZ(d<d e!de dB de'fd!d"Z)	d<de!d#e!dB d$e dB d%ede*e!e'f f
d&d'Z+d(e'e! dB d)e'e! d*e'de,fd+d,Z-d-ed$e de fd.d/Z.d0ede e!ef dB fd1d2Z/d3e!de!dB fd4d5Z0de1fd6d7Z2de1dB fd8d9Z3de1fd:d;Z4dS )=    N)Counter)asdictfieldsis_dataclass)Path)Anyget_args
get_origin)	OmegaConf)init_logger)
get_configget_hf_file_to_dict)file_or_path_exists)_to_dict)current_omni_platformstageomni_conn_cfg	omni_fromomni_toreturnc              
   C   s   i }z | j }t|dr!|dd}|r!t|drt|}nt|}W n ty-   i }Y nw ||d< ||d< ||d< zt| j drI|| j d< W dS t| j d| W dS  tym } ztd	|  W Y d}~dS d}~ww )
z;Inject connector configuration into stage engine arguments.getomni_kv_configNitemsconnector_configomni_from_stageomni_to_stage__setitem__z3Failed to inject omni connector config into stage: )	engine_argshasattrr   dictr   	Exceptionsetattrloggererror)r   r   r   r   omni_conf_dictexisting_args_oce r(   O/home/ubuntu/.local/lib/python3.10/site-packages/vllm_omni/entrypoints/utils.pyinject_omni_kv_config   s0   


r*   modelc                 C   sF   t d| dd}|r!t|tr!d|v r!td|d  d |d S dS )zTry to get class name from diffusers model configuration files.

    Args:
        model: Model name or path

    Returns:
        Model type string if found, None otherwise
    model_index.jsonNrevision_class_namezFound model_type 'z' in model_index.json)r   
isinstancer   r"   debug)r+   model_indexr(   r(   r)   )_try_get_class_name_from_diffusers_config7   s
   	r3   objc                 C   st   dt dtfdd}i }g }|  D ]\}}||r!|t| qt|||< q|r8tdt| d| d |S )aT  Filter dict-like object by removing callables and recursively converting values.

    Converts dict-like objects to regular dicts while filtering out callable values
    that are incompatible with OmegaConf. Recursively processes values through
    _convert_dataclasses_to_dict for nested object conversion.

    Args:
        obj: Dict or dict-like object to filter

    Returns:
        Regular dict with callables filtered out and values recursively converted

    Raises:
        TypeError: If obj doesn't support .items() method
        ValueError: If dict conversion fails unexpectedly
    valuer   c                 S   s&   t | rdS t| tjtjtjtjfS NT)callabler0   typesFunctionType
MethodTypeBuiltinFunctionTypeBuiltinMethodType)r5   r(   r(   r)   _is_callable_valueZ   s   z4_filter_dict_like_object.<locals>._is_callable_valuezFiltered out zR callable object(s) from base_engine_args that are not compatible with OmegaConf: z. )	r   boolr   appendstr_convert_dataclasses_to_dictr"   warninglen)r4   r=   resultfiltered_keyskvr(   r(   r)   _filter_dict_like_objectH   s   rH   c              
   C   s  t | dr| jjdkrzt| W S  ttfy   i  Y S w t| tr't| S t| tr0t	| S t
| r<t| }t|S t| trEt| S t| rKdS t| t	tfr]t| dd | D S t | drt | drt| ttfszt| W S  tttfy   |  Y S w | S )av  Recursively convert non-serializable objects to OmegaConf-compatible types.

    This is needed because OmegaConf cannot handle:
    - Dataclass objects with Literal type annotations (e.g., StructuredOutputsConfig)
    - Counter objects (from collections or vllm.utils)
    - Set objects
    - Callable objects (functions, methods, etc.)
    - Other non-primitive types
    	__class__r   Nc                 s   s     | ]}t |st|V  qd S N)r7   rA   ).0itemr(   r(   r)   	<genexpr>   s    z/_convert_dataclasses_to_dict.<locals>.<genexpr>keysvalues)r   rI   __name__r   	TypeError
ValueErrorr0   r   setlistr   r   rA   rH   r7   tupletyper@   bytesAttributeError)r4   rD   r(   r(   r)   rA   v   s4   



"
rA   c           
      C   s@  zt | dd}|j}W ne ttfyp   t| dddr,t| }|du r+td|  dnBt| dddrfztd| dd}|rFd	|v rF|d	 }ntd
|  W n tye } ztd|  d| |d}~ww td|  dY nw t }| d}t	| | }t
j|rt|S d| d}t	| }	t
j|	sdS t|	S )aE  Resolve the stage config file path from the model name.

    Resolves stage configuration path based on the model type and device type.
    First tries to find a device-specific YAML file from stage_configs/{device_type}/
    directory. If not found, falls back to the default config file.

    Args:
        model: Model name or path (used to determine model_type)

    Returns:
        String path to the stage configuration file

    Raises:
        ValueError: If model_type cannot be determined
        FileNotFoundError: If no stage config file exists for the model type
    T)trust_remote_coder,   Nr-   z4Could not determine model_type for diffusers model: zY. Please ensure the model has 'model_type' in transformer/config.json or model_index.jsonzconfig.json
model_typez6config.json found but missing 'model_type' for model: z&Failed to read config.json for model: z	. Error: z*Could not determine model_type for model: z. Model is not in standard transformers format and does not have model_index.json. Please ensure the model has proper configuration files with 'model_type' fieldz.yamlz'vllm_omni/model_executor/stage_configs/)r   rZ   rR   r    r   r3   r   r   get_default_stage_config_pathPROJECT_ROOTospathexistsr@   )
r+   	hf_configrZ   config_dictr'   default_config_pathmodel_type_strcomplete_config_pathstage_config_filestage_config_pathr(   r(   r)   resolve_model_config_path   sJ   




rg   base_engine_argsc                 C   s0   |du ri }t | }|du rg S t||d}|S )a  Load stage configurations from model's default config file.

    Loads stage configurations based on the model type and device type.
    First tries to load a device-specific YAML file from stage_configs/{device_type}/
    directory. If not found, falls back to the default config file.

    Args:
        model: Model name or path (used to determine model_type)

    Returns:
        List of stage configuration dictionaries

    Raises:
        FileNotFoundError: If no stage config file exists for the model type
    N)config_pathrh   )rg   load_stage_configs_from_yaml)r+   rh   rf   stage_configsr(   r(   r)   load_stage_configs_from_model   s   rl   ri   c           
      C   s   |du ri }t | }|j}|dd}t|}t |}|D ]B}| }t|dr6|jdur6t 	||j}t
|dd}t|dr^|jdur^|dkr^|j}t|d	d
pUd
}	|	|d< ||_||_q|S )zLoad stage configurations from a YAML file.

    Args:
        config_path: Path to the YAML configuration file

    Returns:
        List of stage configuration dictionaries from the file's stage_args
    Nasync_chunkFr   
stage_typellmruntime	diffusionmax_batch_size   max_num_seqs)r
   load
stage_argsr   rA   createcopyr   r   mergegetattrrp   intrm   )
ri   rh   config_datarv   global_async_chunk	stage_argbase_engine_args_tmprn   runtime_cfgrr   r(   r(   r)   rj     s&   	

rj   stage_configs_pathkwargsdefault_stage_cfg_factoryc                 C   sd   |du r&t | }t| |d}|s"|dur | }t|}||fS g }||fS |}t||d}||fS )a  Load stage configurations from model or YAML file with fallback to defaults.

    Args:
        model: Model name or path
        stage_configs_path: Optional path to YAML file containing stage configurations
        kwargs: Engine arguments to merge with stage configs
        default_stage_cfg_factory: Optional callable that takes no args and returns
            default stage config list when no configs are found

    Returns:
        Tuple of (config_path, stage_configs)
    N)rh   )rg   rl   r
   rw   rj   )r+   r   r   r   ri   rk   default_stage_cfgr(   r(   r)   load_and_resolve_stage_configs#  s   
r   output_modalitiesdefault_modalities
stage_listc           	   
   C   s   t |d }| dur'g }| D ]}||vrtd| d q|| q|} n|} z(t|ddD ]}t|| ddrE|| j| v rE|} nq0|dk rO|}W |S W |S  tyn } ztjd	|d
d |}W Y d}~|S d}~ww )zGet the final stage id for e2e.

    Args:
        stage_list: List of stage configurations

    Returns:
        Final stage id for e2e
    rs   NzInvalid output modality: z, ignoring itfinal_outputFr   z`[Orchestrator] Failed to determine final stage for E2E;                 falling back to last: %sT)exc_info)	rC   r"   rB   r?   rangerz   final_output_typer    r1   )	r   r   r   last_stage_idprompt_modalitiesmodality_sidfinal_stage_id_for_e2er'   r(   r(   r)   get_final_stage_id_for_e2eE  sB   
r   clsc                    s   t | st|  dt|tstddtdtdtf fdd dd	 t| D }i }| D ]\}}||vr9q0|| } ||j||< q0|S )
zFilter kwargs to only include fields defined in the dataclass.

    Args:
        cls: Dataclass type
        kwargs: Keyword arguments to filter

    Returns:
        Filtered keyword arguments containing only valid dataclass fields
    z is not a dataclasszkwargs must be a dictionaryr5   
annotationr   c                    s^  |du r| S t |}|du r#t|tr!t|r!t| tr!t|| S | S |tttfv rNt	|}|r4|d nd t| tttfrLt|  fdd| D S | S |tu rut	|}t
|dkr`|d ndt| trsfdd|  D S | S |tju s|ttddu rt	|D ]$}t|trt|rt| trt||   S | |}|| ur|  S q| S | S )	zJRecursively filter nested dict/list values based on dataclass annotations.Nr   c                 3   s    | ]} |V  qd S rJ   r(   )rK   rG   )_filter_valueinnerr(   r)   rM     s    zAfilter_dataclass_kwargs.<locals>._filter_value.<locals>.<genexpr>rs   c                    s   i | ]
\}}| |qS r(   r(   )rK   rF   rG   )r   val_typer(   r)   
<dictcomp>  s    zBfilter_dataclass_kwargs.<locals>._filter_value.<locals>.<dictcomp>	UnionType)r	   r0   rV   r   r   filter_dataclass_kwargsrT   rU   rS   r   rC   r   r8   r   rz   )r5   r   originargsargfilteredr   )r   r   r)   r     s:   


z.filter_dataclass_kwargs.<locals>._filter_valuec                 S   s   i | ]	}|j r|j|qS r(   )initname)rK   fr(   r(   r)   r     s    z+filter_dataclass_kwargs.<locals>.<dictcomp>)r   rR   r0   r   r   r   r   rV   )r   r   valid_fieldsfiltered_kwargsrF   rG   fieldr(   r   r)   r   s  s   

%r   sourcec                    s   t  dott d}|r dd}nt dd}|dur#d|ind}g d}|r5 fdd|D }n	 fdd|D }|rI|pCi }|| |S )a  Build base engine args with tokenizer and parallel configuration.

    Automatically detects whether source is a dict-like object or namespace object.

    Args:
        source: Source object (args namespace or kwargs dict) containing configuration.

    Returns:
        Dictionary containing tokenizer and parallel configuration overrides,
        or None if no configuration is present.
    r   	tokenizerN)tensor_parallel_sizepipeline_parallel_sizedata_parallel_sizedata_parallel_size_localdata_parallel_backenddistributed_executor_backendc                    s*   i | ]}| v r | d ur| | qS rJ   r(   rK   rF   r   r(   r)   r     s   * z*build_base_engine_args.<locals>.<dictcomp>c                    s0   i | ]}t  |rt |d ur|t |qS rJ   )r   rz   r   r   r(   r)   r     s    
)r   r7   rz   r   update)r   is_dict_liker   rh   parallel_keysparallel_overridesr(   r   r)   build_base_engine_args  s   	

r   r^   c              
   C   sZ   zt | ddd}| W  d    W S 1 sw   Y  W d S  tttfy,   Y d S w )Nzutf-8replace)encodingerrors)openreadFileNotFoundErrorPermissionErrorOSError)r^   r   r(   r(   r)   
_read_text  s   (r   c                     s6   t jdrdS tdpd d} t fdd| D S )Nz/.dockerenvTz/proc/1/cgroup )docker
containerdkubepodslibpodpodmanc                 3   s    | ]}| v V  qd S rJ   r(   )rK   mcgr(   r)   rM     s    zin_container.<locals>.<genexpr>)r]   r^   r_   r   any)markersr(   r   r)   in_container  s
   r   c                  C   sj   t d} | dur|  } | dkrdS dS dD ]\}}t d| d}|dur2| |kr/ dS  dS qdS )	z
    Returns:
      True  -> very likely running with --pid=host (host PID namespace)
      False -> very likely isolated PID namespace (default)
      None  -> cannot determine
    z/proc/2/commNkthreaddTF))   rcu_gp)   
rcu_par_gp)
   zksoftirqd/0z/proc/z/comm)r   strip)comm2pidr   commr(   r(   r)   has_pid_host  s   r   c                  C   s   t  } | sdS t S r6   )r   r   )icr(   r(   r)   detect_pid_host  s   r   rJ   )5r]   r8   collectionsr   dataclassesr   r   r   pathlibr   typingr   r   r	   	omegaconfr
   vllm.loggerr   vllm.transformers_utils.configr   r   "vllm.transformers_utils.repo_utilsr   !vllm_omni.entrypoints.stage_utilsr   vllm_omni.platformsr   __file__parentr\   rP   r"   r   r@   r*   r3   rH   rA   rg   rT   rl   rj   rU   r   r{   r   r   r   r   r>   r   r   r   r(   r(   r(   r)   <module>   s`    &!.6>$

"

.@4