From b890e987b6595a4f195e20535a620bea2f0c8576 Mon Sep 17 00:00:00 2001 From: Aaron Sequeira Date: Sun, 14 Sep 2025 19:51:10 +0300 Subject: [PATCH 1/3] FIX: Correctly initialize HuggingFace models in init_chat_model --- libs/langchain/langchain/chat_models/base.py | 88 ++++++++++++------- .../tests/unit_tests/chat_models/test_base.py | 14 +++ 2 files changed, 69 insertions(+), 33 deletions(-) diff --git a/libs/langchain/langchain/chat_models/base.py b/libs/langchain/langchain/chat_models/base.py index d0f54b6a01368..e65970143df3c 100644 --- a/libs/langchain/langchain/chat_models/base.py +++ b/libs/langchain/langchain/chat_models/base.py @@ -93,41 +93,41 @@ def init_chat_model( above). Supported model_provider values and the corresponding integration package are: - - ``openai`` -> ``langchain-openai`` - - ``anthropic`` -> ``langchain-anthropic`` - - ``azure_openai`` -> ``langchain-openai`` - - ``azure_ai`` -> ``langchain-azure-ai`` - - ``google_vertexai`` -> ``langchain-google-vertexai`` - - ``google_genai`` -> ``langchain-google-genai`` - - ``bedrock`` -> ``langchain-aws`` - - ``bedrock_converse`` -> ``langchain-aws`` - - ``cohere`` -> ``langchain-cohere`` - - ``fireworks`` -> ``langchain-fireworks`` - - ``together`` -> ``langchain-together`` - - ``mistralai`` -> ``langchain-mistralai`` - - ``huggingface`` -> ``langchain-huggingface`` - - ``groq`` -> ``langchain-groq`` - - ``ollama`` -> ``langchain-ollama`` - - ``google_anthropic_vertex`` -> ``langchain-google-vertexai`` - - ``deepseek`` -> ``langchain-deepseek`` - - ``ibm`` -> ``langchain-ibm`` - - ``nvidia`` -> ``langchain-nvidia-ai-endpoints`` - - ``xai`` -> ``langchain-xai`` - - ``perplexity`` -> ``langchain-perplexity`` + - ``openai``              -> ``langchain-openai`` + - ``anthropic``           -> ``langchain-anthropic`` + - ``azure_openai``        -> ``langchain-openai`` + - ``azure_ai``            -> ``langchain-azure-ai`` + - ``google_vertexai``     -> ``langchain-google-vertexai`` + - ``google_genai``        -> ``langchain-google-genai`` + - ``bedrock``             -> ``langchain-aws`` + - ``bedrock_converse``    -> ``langchain-aws`` + - ``cohere``              -> ``langchain-cohere`` + - ``fireworks``           -> ``langchain-fireworks`` + - ``together``            -> ``langchain-together`` + - ``mistralai``           -> ``langchain-mistralai`` + - ``huggingface``         -> ``langchain-huggingface`` + - ``groq``                -> ``langchain-groq`` + - ``ollama``              -> ``langchain-ollama`` + - ``google_anthropic_vertex``    -> ``langchain-google-vertexai`` + - ``deepseek``            -> ``langchain-deepseek`` + - ``ibm``                 -> ``langchain-ibm`` + - ``nvidia``              -> ``langchain-nvidia-ai-endpoints`` + - ``xai``                 -> ``langchain-xai`` + - ``perplexity``          -> ``langchain-perplexity`` Will attempt to infer model_provider from model if not specified. The following providers will be inferred based on these model prefixes: - ``gpt-3...`` | ``gpt-4...`` | ``o1...`` -> ``openai`` - - ``claude...`` -> ``anthropic`` - - ``amazon...`` -> ``bedrock`` - - ``gemini...`` -> ``google_vertexai`` - - ``command...`` -> ``cohere`` - - ``accounts/fireworks...`` -> ``fireworks`` - - ``mistral...`` -> ``mistralai`` - - ``deepseek...`` -> ``deepseek`` - - ``grok...`` -> ``xai`` - - ``sonar...`` -> ``perplexity`` + - ``claude...``                       -> ``anthropic`` + - ``amazon...``                       -> ``bedrock`` + - ``gemini...``                       -> ``google_vertexai`` + - ``command...``                      -> ``cohere`` + - ``accounts/fireworks...``           -> ``fireworks`` + - ``mistral...``                      -> ``mistralai`` + - ``deepseek...``                     -> ``deepseek`` + - ``grok...``                         -> ``xai`` + - ``sonar...``                        -> ``perplexity`` configurable_fields: Which model parameters are configurable: - None: No configurable fields. @@ -412,10 +412,32 @@ def _init_chat_model_helper( return ChatMistralAI(model=model, **kwargs) # type: ignore[call-arg,unused-ignore] if model_provider == "huggingface": - _check_pkg("langchain_huggingface") - from langchain_huggingface import ChatHuggingFace + try: + from langchain_huggingface.chat_models import ChatHuggingFace + from langchain_huggingface.llms import HuggingFacePipeline + except ImportError as e: + raise ImportError( + "Please install langchain-huggingface to use HuggingFace models." + ) from e + + # The 'task' kwarg is required by from_model_id but not the base constructor. + # We pop it from kwargs to avoid the Pydantic 'extra_forbidden' error. + task = kwargs.pop("task", None) + if not task: + raise ValueError( + "The 'task' keyword argument is required for HuggingFace models. " + "For example: task='text-generation'." + ) + + # Initialize the base LLM pipeline with the model and arguments + llm = HuggingFacePipeline.from_model_id( + model_id=model, + task=task, + **kwargs, # Pass remaining kwargs like `device` + ) - return ChatHuggingFace(model_id=model, **kwargs) + # Pass the initialized LLM to the chat wrapper + return ChatHuggingFace(llm=llm) if model_provider == "groq": _check_pkg("langchain_groq") from langchain_groq import ChatGroq diff --git a/libs/langchain/tests/unit_tests/chat_models/test_base.py b/libs/langchain/tests/unit_tests/chat_models/test_base.py index 611f251b8162c..5e3f077083af4 100644 --- a/libs/langchain/tests/unit_tests/chat_models/test_base.py +++ b/libs/langchain/tests/unit_tests/chat_models/test_base.py @@ -6,6 +6,7 @@ from langchain_core.language_models import BaseChatModel from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnableConfig, RunnableSequence +from langchain_huggingface.chat_models import ChatHuggingFace from pydantic import SecretStr from langchain.chat_models.base import __all__, init_chat_model @@ -289,3 +290,16 @@ def test_configurable_with_default() -> None: prompt = ChatPromptTemplate.from_messages([("system", "foo")]) chain = prompt | model_with_config assert isinstance(chain, RunnableSequence) + + +def test_init_chat_model_huggingface() -> None: + """Test that init_chat_model works with huggingface.""" + model_name = "google-bert/bert-base-uncased" + + llm = init_chat_model( + model=model_name, + model_provider="huggingface", + task="text-generation", + ) + assert isinstance(llm, ChatHuggingFace) + assert llm.llm.model_id == model_name From 73d2bc78485e0bb2ba6067d22f953cb4e08bd03c Mon Sep 17 00:00:00 2001 From: Aaron Sequeira Date: Tue, 30 Sep 2025 22:42:03 +0300 Subject: [PATCH 2/3] WIP: Saving local changes --- libs/langchain/langchain/chat_models/base.py | 74 +++++++++++--------- 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/libs/langchain/langchain/chat_models/base.py b/libs/langchain/langchain/chat_models/base.py index e65970143df3c..919aaaa0789a0 100644 --- a/libs/langchain/langchain/chat_models/base.py +++ b/libs/langchain/langchain/chat_models/base.py @@ -37,7 +37,7 @@ def init_chat_model( model: str, *, model_provider: Optional[str] = None, - configurable_fields: Literal[None] = None, + configurable_fields: None = None, config_prefix: Optional[str] = None, **kwargs: Any, ) -> BaseChatModel: ... @@ -45,10 +45,10 @@ def init_chat_model( @overload def init_chat_model( - model: Literal[None] = None, + model: None = None, *, model_provider: Optional[str] = None, - configurable_fields: Literal[None] = None, + configurable_fields: None = None, config_prefix: Optional[str] = None, **kwargs: Any, ) -> _ConfigurableModel: ... @@ -93,41 +93,41 @@ def init_chat_model( above). Supported model_provider values and the corresponding integration package are: - - ``openai``              -> ``langchain-openai`` - - ``anthropic``           -> ``langchain-anthropic`` - - ``azure_openai``        -> ``langchain-openai`` - - ``azure_ai``            -> ``langchain-azure-ai`` - - ``google_vertexai``     -> ``langchain-google-vertexai`` - - ``google_genai``        -> ``langchain-google-genai`` - - ``bedrock``             -> ``langchain-aws`` - - ``bedrock_converse``    -> ``langchain-aws`` - - ``cohere``              -> ``langchain-cohere`` - - ``fireworks``           -> ``langchain-fireworks`` - - ``together``            -> ``langchain-together`` - - ``mistralai``           -> ``langchain-mistralai`` - - ``huggingface``         -> ``langchain-huggingface`` - - ``groq``                -> ``langchain-groq`` - - ``ollama``              -> ``langchain-ollama`` - - ``google_anthropic_vertex``    -> ``langchain-google-vertexai`` - - ``deepseek``            -> ``langchain-deepseek`` - - ``ibm``                 -> ``langchain-ibm`` - - ``nvidia``              -> ``langchain-nvidia-ai-endpoints`` - - ``xai``                 -> ``langchain-xai`` - - ``perplexity``          -> ``langchain-perplexity`` + - ``openai`` -> ``langchain-openai`` + - ``anthropic`` -> ``langchain-anthropic`` + - ``azure_openai`` -> ``langchain-openai`` + - ``azure_ai`` -> ``langchain-azure-ai`` + - ``google_vertexai`` -> ``langchain-google-vertexai`` + - ``google_genai`` -> ``langchain-google-genai`` + - ``bedrock`` -> ``langchain-aws`` + - ``bedrock_converse`` -> ``langchain-aws`` + - ``cohere`` -> ``langchain-cohere`` + - ``fireworks`` -> ``langchain-fireworks`` + - ``together`` -> ``langchain-together`` + - ``mistralai`` -> ``langchain-mistralai`` + - ``huggingface`` -> ``langchain-huggingface`` + - ``groq`` -> ``langchain-groq`` + - ``ollama`` -> ``langchain-ollama`` + - ``google_anthropic_vertex`` -> ``langchain-google-vertexai`` + - ``deepseek`` -> ``langchain-deepseek`` + - ``ibm`` -> ``langchain-ibm`` + - ``nvidia`` -> ``langchain-nvidia-ai-endpoints`` + - ``xai`` -> ``langchain-xai`` + - ``perplexity`` -> ``langchain-perplexity`` Will attempt to infer model_provider from model if not specified. The following providers will be inferred based on these model prefixes: - ``gpt-3...`` | ``gpt-4...`` | ``o1...`` -> ``openai`` - - ``claude...``                       -> ``anthropic`` - - ``amazon...``                       -> ``bedrock`` - - ``gemini...``                       -> ``google_vertexai`` - - ``command...``                      -> ``cohere`` - - ``accounts/fireworks...``           -> ``fireworks`` - - ``mistral...``                      -> ``mistralai`` - - ``deepseek...``                     -> ``deepseek`` - - ``grok...``                         -> ``xai`` - - ``sonar...``                        -> ``perplexity`` + - ``claude...`` -> ``anthropic`` + - ``amazon...`` -> ``bedrock`` + - ``gemini...`` -> ``google_vertexai`` + - ``command...`` -> ``cohere`` + - ``accounts/fireworks...`` -> ``fireworks`` + - ``mistral...`` -> ``mistralai`` + - ``deepseek...`` -> ``deepseek`` + - ``grok...`` -> ``xai`` + - ``sonar...`` -> ``perplexity`` configurable_fields: Which model parameters are configurable: - None: No configurable fields. @@ -273,7 +273,10 @@ class GetPopulation(BaseModel): ) configurable_model_with_tools = configurable_model.bind_tools( - [GetWeather, GetPopulation] + [ + GetWeather, + GetPopulation, + ] ) configurable_model_with_tools.invoke( "Which city is hotter today and which is bigger: LA or NY?" @@ -516,7 +519,7 @@ def _init_chat_model_helper( def _attempt_infer_model_provider(model_name: str) -> Optional[str]: - if any(model_name.startswith(pre) for pre in ("gpt-3", "gpt-4", "o1", "o3")): + if any(model_name.startswith(pre) for pre in ("gpt-", "o1", "o3")): return "openai" if model_name.startswith("claude"): return "anthropic" @@ -977,3 +980,4 @@ def with_structured_output( **kwargs: Any, ) -> Runnable[LanguageModelInput, Union[dict, BaseModel]]: return self.__getattr__("with_structured_output")(schema, **kwargs) + From 3dc1292bd3414e8bf033f3090eabb95d4876b54d Mon Sep 17 00:00:00 2001 From: Chester Curme Date: Wed, 1 Oct 2025 10:54:15 -0400 Subject: [PATCH 3/3] remove extraneous changes --- libs/langchain/langchain/chat_models/base.py | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/libs/langchain/langchain/chat_models/base.py b/libs/langchain/langchain/chat_models/base.py index 174a1edb410d1..21e248d4180a7 100644 --- a/libs/langchain/langchain/chat_models/base.py +++ b/libs/langchain/langchain/chat_models/base.py @@ -38,7 +38,6 @@ def init_chat_model( *, model_provider: Optional[str] = None, configurable_fields: None = None, - configurable_fields: None = None, config_prefix: Optional[str] = None, **kwargs: Any, ) -> BaseChatModel: ... @@ -46,12 +45,10 @@ def init_chat_model( @overload def init_chat_model( - model: None = None, model: None = None, *, model_provider: Optional[str] = None, configurable_fields: None = None, - configurable_fields: None = None, config_prefix: Optional[str] = None, **kwargs: Any, ) -> _ConfigurableModel: ... @@ -131,16 +128,6 @@ def init_chat_model( - ``deepseek...`` -> ``deepseek`` - ``grok...`` -> ``xai`` - ``sonar...`` -> ``perplexity`` - - ``gpt-3...`` | ``gpt-4...`` | ``o1...`` -> ``openai`` - - ``claude...`` -> ``anthropic`` - - ``amazon...`` -> ``bedrock`` - - ``gemini...`` -> ``google_vertexai`` - - ``command...`` -> ``cohere`` - - ``accounts/fireworks...`` -> ``fireworks`` - - ``mistral...`` -> ``mistralai`` - - ``deepseek...`` -> ``deepseek`` - - ``grok...`` -> ``xai`` - - ``sonar...`` -> ``perplexity`` configurable_fields: Which model parameters are configurable: - None: No configurable fields. @@ -290,10 +277,6 @@ class GetPopulation(BaseModel): GetWeather, GetPopulation, ] - [ - GetWeather, - GetPopulation, - ] ) configurable_model_with_tools.invoke( "Which city is hotter today and which is bigger: LA or NY?" @@ -536,7 +519,6 @@ def _init_chat_model_helper( def _attempt_infer_model_provider(model_name: str) -> Optional[str]: - if any(model_name.startswith(pre) for pre in ("gpt-", "o1", "o3")): if any(model_name.startswith(pre) for pre in ("gpt-", "o1", "o3")): return "openai" if model_name.startswith("claude"): @@ -998,4 +980,3 @@ def with_structured_output( **kwargs: Any, ) -> Runnable[LanguageModelInput, Union[dict, BaseModel]]: return self.__getattr__("with_structured_output")(schema, **kwargs) -