U
    ho3                     @  s   d dl mZ d dlZd dlZd dlmZmZmZm	Z	m
Z
 d dlmZ d dlmZ d dlmZ d dlmZmZmZ dZd	Zd
ZdZeeZeddddG dd deZdS )    )annotationsN)AnyIteratorListMappingOptional)
deprecated)CallbackManagerForLLMRun)BaseLLM)
GenerationGenerationChunk	LLMResultZgpt2text-generation)text2text-generationr   summarizationtranslation   z0.0.37z1.0z)langchain_huggingface.HuggingFacePipeline)ZsinceZremovalZalternative_importc                   @  s   e Zd ZU dZded< eZded< dZded< dZded	< e	Z
d
ed< G dd dZeddddde	fdddddddd
dd d
ddZeddddZeddddZd&ddddddd d!Zd'ddddd"d#d$d%ZdS )(HuggingFacePipelinea\  HuggingFace Pipeline API.

    To use, you should have the ``transformers`` python package installed.

    Only supports `text-generation`, `text2text-generation`, `summarization` and
    `translation`  for now.

    Example using from_model_id:
        .. code-block:: python

            from langchain_community.llms import HuggingFacePipeline
            hf = HuggingFacePipeline.from_model_id(
                model_id="gpt2",
                task="text-generation",
                pipeline_kwargs={"max_new_tokens": 10},
            )
    Example passing pipeline in directly:
        .. code-block:: python

            from langchain_community.llms import HuggingFacePipeline
            from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline

            model_id = "gpt2"
            tokenizer = AutoTokenizer.from_pretrained(model_id)
            model = AutoModelForCausalLM.from_pretrained(model_id)
            pipe = pipeline(
                "text-generation", model=model, tokenizer=tokenizer, max_new_tokens=10
            )
            hf = HuggingFacePipeline(pipeline=pipe)
    r   pipelinestrmodel_idNzOptional[dict]model_kwargspipeline_kwargsint
batch_sizec                   @  s   e Zd ZdZdS )zHuggingFacePipeline.ConfigZforbidN)__name__
__module____qualname__extra r   r   Q/tmp/pip-unpacked-wheel-9gdii04g/langchain_community/llms/huggingface_pipeline.pyConfigH   s   r!   defaultzOptional[int]zOptional[str])
r   taskbackenddevice
device_mapr   r   r   kwargsreturnc	              
   K  sz  z$ddl m}
m}m} ddl m} W n tk
r@   tdY nX |pHi }|j|f|}z>|dkr|dkrzddlm} W n tk
r   tdY nX z|j|f|}W q t	k
r   |j|fd	d
i|}Y qX n|
j|f|}n|dkr|dkrpzddlm
} W n tk
r,   tdY nX z|j|f|}W n, t	k
rl   |j|fd	d
i|}Y nX n|j|f|}ntd| dt dW n6 tk
r } ztd| d|W 5 d}~X Y nX |jdkr|jj|_t|ddst|ddr,|dk	r,|dkr,td| d d}|dk	rtjddk	r|dkrddl}|j }|dk sx||krtd| d| d|dk	r|dk rd}|dk	r|dk r|dkrtd| |dk	r|dk	r|dkrtd d |krd!d" | D }|pi }|f |||||||d#|}|jtkr`td|j dt d| f |||||d$|	S )%z5Construct the pipeline object from model_id and task.r   )AutoModelForCausalLMAutoModelForSeq2SeqLMAutoTokenizer)r   z`Could not import transformers python package. Please install it with `pip install transformers`.r   Zopenvino)OVModelForCausalLMzlCould not import optimum-intel python package. Please install it with: pip install 'optimum[openvino,nncf]' exportT)r   r   r   )OVModelForSeq2SeqLMGot invalid task , currently only  are supportedzCould not load the z# model due to missing dependencies.NZis_loaded_in_4bitFZis_loaded_in_8bitr"   z+Setting the `device` argument to None from z to avoid the error caused by attempting to move the model that was already loaded on the GPU using the Accelerate module to the same or another device.torchr#   zGot device==z', device is required to be within [-1, )zDevice has %d GPUs available. Provide device={deviceId} to `from_model_id` to use availableGPUs for execution. deviceId is -1 (default) for CPU and can be a positive integer associated with CUDA device id.z6Please set device for OpenVINO through: `model_kwargs`trust_remote_codec                 S  s   i | ]\}}|d kr||qS )r5   r   ).0kvr   r   r    
<dictcomp>   s      z5HuggingFacePipeline.from_model_id.<locals>.<dictcomp>)r$   model	tokenizerr&   r'   r   r   )r   r   r   r   r   )transformersr*   r+   r,   r   ImportErrorZfrom_pretrainedZoptimum.intel.openvinor-   	Exceptionr/   
ValueErrorVALID_TASKSZ	pad_tokenconfigZeos_token_idZpad_token_idgetattrloggerwarning	importlibutil	find_specr3   ZcudaZdevice_countitemsr$   )clsr   r$   r%   r&   r'   r   r   r   r(   r*   r+   r,   Zhf_pipelineZ_model_kwargsr;   r-   r:   r/   er3   Zcuda_device_countZ_pipeline_kwargsr   r   r   r    from_model_idK   s   














z!HuggingFacePipeline.from_model_idzMapping[str, Any])r)   c                 C  s   | j | j| jdS )zGet the identifying parameters.r   r   r   rL   selfr   r   r    _identifying_params   s    z'HuggingFacePipeline._identifying_paramsc                 C  s   dS )NZhuggingface_pipeliner   rM   r   r   r    	_llm_type   s    zHuggingFacePipeline._llm_typez	List[str]zOptional[List[str]]z"Optional[CallbackManagerForLLMRun]r   )promptsstoprun_managerr(   r)   c                 K  s2  g }| j r| j ni }|d|}|dd}tdt|| jD ]}	||	|	| j  }
| j|
f|}t|D ]\}}t|tr|d }| jj	dkr|d }n\| jj	dkr|d }nF| jj	dkr|d	 }n0| jj	d
kr|d }nt
d| jj	 dt d|r|t|
| d  }|| qjq>tdd |D dS )Nr   skip_promptFr   r   Zgenerated_textr   r   Zsummary_textr   Ztranslation_textr0   r1   r2   c                 S  s   g | ]}t |d gqS )text)r   )r6   rV   r   r   r    
<listcomp>0  s     z1HuggingFacePipeline._generate.<locals>.<listcomp>)Zgenerations)r   getrangelenr   r   	enumerate
isinstancelistr$   r?   r@   appendr   )rN   rQ   rR   rS   r(   Ztext_generationsZdefault_pipeline_kwargsr   rT   iZbatch_prompts	responsesjresponserV   r   r   r    	_generate   s>    




zHuggingFacePipeline._generatezIterator[GenerationChunk])promptrR   rS   r(   r)   c                 +  s  ddl m} dd lddlm}m}m} |di }	|dd}
|d k	rV| jj	
|}|p\g  G  fddd|}|| g}| jj	|d	d
}|| jj	d|
dd}t|f||d|	}|| jjj|d}|  |D ](}t|d}|r|j|j|d |V  qd S )Nr   )Thread)StoppingCriteriaStoppingCriteriaListTextIteratorStreamerr   rT   Tc                      s$   e Zd Zddddd fddZdS )	z1HuggingFacePipeline._stream.<locals>.StopOnTokensztorch.LongTensorztorch.FloatTensorr   bool)	input_idsscoresr(   r)   c                   s$    D ]}|d d |kr dS qdS )Nr   r#   TFr   )rN   rj   rk   r(   Zstop_id)stopping_ids_listr   r    __call__K  s    z:HuggingFacePipeline._stream.<locals>.StopOnTokens.__call__N)r   r   r   rm   r   rl   r3   r   r    StopOnTokensJ  s   ro   pt)Zreturn_tensorsg      N@)timeoutrT   Zskip_special_tokens)streamerstopping_criteria)targetr(   rU   )chunk)	threadingre   r3   r<   rf   rg   rh   rX   r   r;   Zconvert_tokens_to_idsdictr:   generatestartr   Zon_llm_new_tokenrV   )rN   rd   rR   rS   r(   re   rf   rg   rh   r   rT   ro   rs   inputsrr   Zgeneration_kwargst1charru   r   rn   r    _stream3  s@    
zHuggingFacePipeline._stream)NN)NN)r   r   r   __doc____annotations__DEFAULT_MODEL_IDr   r   r   DEFAULT_BATCH_SIZEr   r!   classmethodrK   propertyrO   rP   rc   r}   r   r   r   r    r      s4   
$ '  7  r   )
__future__r   importlib.utilrE   loggingtypingr   r   r   r   r   Zlangchain_core._api.deprecationr   Zlangchain_core.callbacksr	   Z#langchain_core.language_models.llmsr
   Zlangchain_core.outputsr   r   r   r   ZDEFAULT_TASKr@   r   	getLoggerr   rC   r   r   r   r   r    <module>   s$   
