langchain-ai / langchain-google

MIT License
75 stars 78 forks source link

AttributeError: 'int' object has no attribute 'name' #57

Open rvasa779 opened 3 months ago

rvasa779 commented 3 months ago

I am using ChatGoogleGenerativeAI (langchain=0.1.11, langchain-google-genai=0.0.9). Once I get the response from Google Gemini Pro I see the below error:

.venv\lib\site-packages\langchain_google_genai\chat_models.py", line 414, in _response_to_result generation_info["finish_reason"] = candidate.finish_reason.name AttributeError: 'int' object has no attribute 'name'

When I print candidate.finish_reason I get the value: 1 (Expecting STOP)

lkuligin commented 3 months ago

can you share a reproducible snippet, please?

edwardjarchibald commented 3 months ago

I got the same error when trying to run this very simple example from the LangChain website. The issue is that in chat_models.py _response_to_result() the candidate.finish_reason is of type 'int' and not of type 'FinishReason'. Just looking at this now since I want to move forward.

from langchain_google_genai import ChatGoogleGenerativeAI

llm = ChatGoogleGenerativeAI(model="gemini-pro")
result = llm.invoke("Write a ballad about LangChain")
print(result.content)
rvasa779 commented 3 months ago

I got the same error when trying to run this very simple example from the LangChain website. The issue is that in chat_models.py _response_to_result() the candidate.finish_reason is of type 'int' and not of type 'FinishReason'. Just looking at this now since I want to move forward.

from langchain_google_genai import ChatGoogleGenerativeAI

llm = ChatGoogleGenerativeAI(model="gemini-pro")
result = llm.invoke("Write a ballad about LangChain")
print(result.content)

Yes, I am able to reproduce it just like that

edwardjarchibald commented 3 months ago

I was able to figure out the issue, at least enough to make forward progress. In chat_models.py in this project there were two different deserialization techniques need. Some of the data coming back from Gemini was serialized using google protobufs and some of the data apparently used the code in proto.Message The error that we hit was because the deserialization needed to use google.protobuf.json_format.MessageToDict() but it was using the proto.Message.to_dict() In one place in chat_models.py Once that was resolved I hit another issue that prevented the content from coming back and that was that an instance of function_call was seen in the response from Gemini but it had no name etc. and so the branch of the code was never executed that collected the content. Adding a test for a non-blank name did the trick. I want to do a bit more research as to why there was a non-functional function call in the response but if all is OK then I will create a branch and do a commit of my single-file change.

rvasa779 commented 3 months ago

I was able to figure out the issue, at least enough to make forward progress. In chat_models.py in this project there were two different deserialization techniques need. Some of the data coming back from Gemini was serialized using google protobufs and some of the data apparently used the code in proto.Message The error that we hit was because the deserialization needed to use google.protobuf.json_format.MessageToDict() but it was using the proto.Message.to_dict() In one place in chat_models.py Once that was resolved I hit another issue that prevented the content from coming back and that was that an instance of function_call was seen in the response from Gemini but it had no name etc. and so the branch of the code was never executed that collected the content. Adding a test for a non-blank name did the trick. I want to do a bit more research as to why there was a non-functional function call in the response but if all is OK then I will create a branch and do a commit of my single-file change.

But this is not the solution. Specially if I have multiple LLM support using configurable_alternatives. We have to keep using proto.Message.to_dict() in chat_models.py. Having said that I did not find reference where google.protobuf.json_format.MessageToDict() is being used.

rvasa779 commented 3 months ago

I was able to figure out the issue, at least enough to make forward progress. In chat_models.py in this project there were two different deserialization techniques need. Some of the data coming back from Gemini was serialized using google protobufs and some of the data apparently used the code in proto.Message The error that we hit was because the deserialization needed to use google.protobuf.json_format.MessageToDict() but it was using the proto.Message.to_dict() In one place in chat_models.py Once that was resolved I hit another issue that prevented the content from coming back and that was that an instance of function_call was seen in the response from Gemini but it had no name etc. and so the branch of the code was never executed that collected the content. Adding a test for a non-blank name did the trick. I want to do a bit more research as to why there was a non-functional function call in the response but if all is OK then I will create a branch and do a commit of my single-file change.

I am seeing an example implemented with GoogleGeminiPro here: https://github.com/langchain-ai/chat-langchain/blob/a8546939455c1e09b8cef6a3c3c0baa788a9d145/backend/chain.py. I am thinking how is this working?

rvasa779 commented 2 months ago

Hi. Trying to follow up on this again.

I am still unable to get over this issue still.

I tried uninstalling all dependency and reinstall them. I got an error/warning while installing langchain-google-genai dependency.

`ERROR: After October 2020 you may experience errors when installing or updating packages. This is because pip will change the way that it resolves dependency conflicts.

We recommend you use --use-feature=2020-resolver to test your packages with the new resolver before it becomes the default.

proto-plus 1.23.0 requires protobuf<5.0.0dev,>=3.19.0, but you'll have protobuf 5.26.1 which is incompatible. googleapis-common-protos 1.63.0 requires protobuf!=3.20.0,!=3.20.1,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<5.0.0.dev0,>=3.19.5, but you'll have protobuf 5.26.1 which is incompatible. google-api-core 2.18.0 requires protobuf!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<5.0.0.dev0,>=3.19.5, but you'll have protobuf 5.26.1 which is incompatible. google-ai-generativelanguage 0.4.0 requires protobuf!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<5.0.0dev,>=3.19.5, but you'll have protobuf 5.26.1 which is incompatible. Successfully installed cachetools-5.3.3 google-ai-generativelanguage-0.4.0 google-api-core-2.18.0 google-auth-2.29.0 google-generativeai-0.4.1 googleapis-common-protos-1.63.0 langchain-google-genai-1.0.1 proto-plus-1.23.0 protobuf-5.26.1 pyasn1-0.6.0 pyasn1-modules-0.4.0 rsa-4.9`

Some how I fell this is related to my error. Because when I tried debugging the below line in .venv\Lib\site-packages\langchain_google_genai\chat_models.py

`def _response_to_result( response: glm.GenerateContentResponse, stream: bool = False, ) -> ChatResult: """Converts a PaLM API response into a LangChain ChatResult.""" llm_output = {"prompt_feedback": proto.Message.to_dict(response.prompt_feedback)}

generations: List[ChatGeneration] = []

for candidate in response.candidates:
    generation_info = {}
    if candidate.finish_reason:
        generation_info["finish_reason"] = candidate.finish_reason.name`

Once I get the type of response.candidates as "response.candidates: <class 'proto.marshal.collections.repeated.RepeatedComposite'>" (This being correct) and the other time I get it as "<class 'google.protobuf.pyext._message.RepeatedCompositeContainer'>" (This is where I get the error: Caught an exception: AttributeError - 'int' object has no attribute 'name')

The difference between both the implementation is once I am executing the LLM as regular python program and when i run the same code via azure functions I get the error.

rvasa779 commented 1 month ago

project there were two different deserialization techniques need. Some of the data coming back from Gemini was serialized using google protobufs and some of the data apparently used the code in proto.Message The error that we hit was because the deserialization needed to use google.protobuf.json_format.MessageToDict() but it was using the proto.Message.to_dict() In one place in chat_models.py Once that was resolved I hit another issue that prevented the content from coming back and that was that an instance of function_call was seen in the response from Gemini but it had no name etc. and so the branch of the code was never executed that collected the content. Adding a test for a non-blank name did the trick. I want to do a bit more research as to why there was a non-functional function call in the response but if all is O

Was there a resolution that you found?

torvicvasil commented 1 month ago

I'm getting the same error using the langchain-google-vertexai==1.0.3. Before that version everything worked fine. Now I can't even call a simple llm invoke. I get the error:

`--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Cell In[10], line 1 ----> 1 llm.invoke("What is AI?")

File /opt/anaconda3/envs/ai2/lib/python3.11/site-packages/langchain_core/language_models/llms.py:276, in BaseLLM.invoke(self, input, config, stop, kwargs) 266 def invoke( 267 self, 268 input: LanguageModelInput, (...) 272 kwargs: Any, 273 ) -> str: 274 config = ensure_config(config) 275 return ( --> 276 self.generate_prompt( 277 [self._convert_input(input)], 278 stop=stop, 279 callbacks=config.get("callbacks"), 280 tags=config.get("tags"), 281 metadata=config.get("metadata"), 282 run_name=config.get("run_name"), 283 run_id=config.pop("run_id", None), 284 **kwargs, 285 ) 286 .generations[0][0] 287 .text 288 )

File /opt/anaconda3/envs/ai2/lib/python3.11/site-packages/langchain_core/language_models/llms.py:633, in BaseLLM.generate_prompt(self, prompts, stop, callbacks, kwargs) 625 def generate_prompt( 626 self, 627 prompts: List[PromptValue], (...) 630 kwargs: Any, 631 ) -> LLMResult: 632 prompt_strings = [p.to_string() for p in prompts] --> 633 return self.generate(prompt_strings, stop=stop, callbacks=callbacks, **kwargs)

File /opt/anaconda3/envs/ai2/lib/python3.11/site-packages/langchain_core/language_models/llms.py:803, in BaseLLM.generate(self, prompts, stop, callbacks, tags, metadata, run_name, run_id, kwargs) 788 if (self.cache is None and get_llm_cache() is None) or self.cache is False: 789 run_managers = [ 790 callback_manager.on_llm_start( 791 dumpd(self), (...) 801 ) 802 ] --> 803 output = self._generate_helper( 804 prompts, stop, run_managers, bool(new_arg_supported), kwargs 805 ) 806 return output 807 if len(missing_prompts) > 0:

File /opt/anaconda3/envs/ai2/lib/python3.11/site-packages/langchain_core/language_models/llms.py:670, in BaseLLM._generate_helper(self, prompts, stop, run_managers, new_arg_supported, **kwargs) 668 for run_manager in run_managers: 669 run_manager.on_llm_error(e, response=LLMResult(generations=[])) --> 670 raise e 671 flattened_outputs = output.flatten() 672 for manager, flattened_output in zip(run_managers, flattened_outputs):

File /opt/anaconda3/envs/ai2/lib/python3.11/site-packages/langchain_core/language_models/llms.py:657, in BaseLLM._generate_helper(self, prompts, stop, run_managers, new_arg_supported, kwargs) 647 def _generate_helper( 648 self, 649 prompts: List[str], (...) 653 kwargs: Any, 654 ) -> LLMResult: 655 try: 656 output = ( --> 657 self._generate( 658 prompts, 659 stop=stop, 660 # TODO: support multiple run managers 661 run_manager=run_managers[0] if run_managers else None, 662 **kwargs, 663 ) 664 if new_arg_supported 665 else self._generate(prompts, stop=stop) 666 ) 667 except BaseException as e: 668 for run_manager in run_managers:

File /opt/anaconda3/envs/ai2/lib/python3.11/site-packages/langchain_google_vertexai/llms.py:247, in VertexAI._generate(self, prompts, stop, run_manager, stream, **kwargs) 244 else: 245 usage_metadata = res.raw_prediction_response.metadata 246 generations.append( --> 247 [ 248 self._candidate_to_generation(r, usage_metadata=usage_metadata) 249 for r in res.candidates 250 ] 251 ) 252 return LLMResult(generations=generations)

File /opt/anaconda3/envs/ai2/lib/python3.11/site-packages/langchain_google_vertexai/llms.py:248, in (.0) 244 else: 245 usage_metadata = res.raw_prediction_response.metadata 246 generations.append( 247 [ --> 248 self._candidate_to_generation(r, usage_metadata=usage_metadata) 249 for r in res.candidates 250 ] 251 ) 252 return LLMResult(generations=generations)

File /opt/anaconda3/envs/ai2/lib/python3.11/site-packages/langchain_google_vertexai/llms.py:197, in VertexAI._candidate_to_generation(self, response, stream, usage_metadata) 189 def _candidate_to_generation( 190 self, 191 response: Union[Candidate, TextGenerationResponse], (...) 194 usage_metadata: Optional[Dict] = None, 195 ) -> GenerationChunk: 196 """Converts a stream response to a generation chunk.""" --> 197 generation_info = get_generation_info( 198 response, 199 self._is_gemini_model, 200 stream=stream, 201 usage_metadata=usage_metadata, 202 ) 203 try: 204 text = response.text

File /opt/anaconda3/envs/ai2/lib/python3.11/site-packages/langchain_google_vertexai/_utils.py:128, in get_generation_info(candidate, is_gemini, stream, usage_metadata) 117 def get_generation_info( 118 candidate: Union[TextGenerationResponse, Candidate], 119 is_gemini: bool, (...) 122 usage_metadata: Optional[Dict] = None, 123 ) -> Dict[str, Any]: 124 if is_gemini: 125 # https://cloud.google.com/vertex-ai/docs/generative-ai/model-reference/gemini#response_body 126 info = { 127 "is_blocked": any([rating.blocked for rating in candidate.safety_ratings]), --> 128 "safety_ratings": [ 129 { 130 "category": rating.category.name, 131 "probability_label": rating.probability.name, 132 "blocked": rating.blocked, 133 } 134 for rating in candidate.safety_ratings 135 ], 136 "citation_metadata": ( 137 proto.Message.to_dict(candidate.citation_metadata) 138 if candidate.citation_metadata 139 else None 140 ), 141 } 142 if usage_metadata: 143 info["usage_metadata"] = usage_metadata

File /opt/anaconda3/envs/ai2/lib/python3.11/site-packages/langchain_google_vertexai/_utils.py:130, in (.0) 117 def get_generation_info( 118 candidate: Union[TextGenerationResponse, Candidate], 119 is_gemini: bool, (...) 122 usage_metadata: Optional[Dict] = None, 123 ) -> Dict[str, Any]: 124 if is_gemini: 125 # https://cloud.google.com/vertex-ai/docs/generative-ai/model-reference/gemini#response_body 126 info = { 127 "is_blocked": any([rating.blocked for rating in candidate.safety_ratings]), 128 "safety_ratings": [ 129 { --> 130 "category": rating.category.name, 131 "probability_label": rating.probability.name, 132 "blocked": rating.blocked, 133 } 134 for rating in candidate.safety_ratings 135 ], 136 "citation_metadata": ( 137 proto.Message.to_dict(candidate.citation_metadata) 138 if candidate.citation_metadata 139 else None 140 ), 141 } 142 if usage_metadata: 143 info["usage_metadata"] = usage_metadata

AttributeError: 'int' object has no attribute 'name' ` My code:

from langchain_google_vertexai import VertexAI llm = VertexAI(model="gemini-pro") llm.invoke("What is AI?")

With version langchain-google-vertexai==1.0.1 I don't have any problems.

torvicvasil commented 2 weeks ago

Hi, could you find the solution for this problem?

rvasa779 commented 2 weeks ago

Hi, could you find the solution for this problem?

No, I am still unable to figure out what is the issue

rvasa779 commented 2 weeks ago

Please use the below as dependency and it will resolve the issue:

googleapis-common-protos==1.56.2 protobuf==3.20.3