mem0 icon indicating copy to clipboard operation
mem0 copied to clipboard

ValueError Shape when using gemini for embedding

Open renanmoretto opened this issue 7 months ago • 4 comments

🐛 Describe the bug

getting an error from qdrant when using gemini for embedding if i change to openai, it works

import os

from mem0 import Memory
from mem0.configs.base import MemoryConfig, EmbedderConfig, LlmConfig


os.environ["OPENAI_API_KEY"] = '...'
os.environ["GOOGLE_API_KEY"] = '...'

custom_config = MemoryConfig(
    embedder=EmbedderConfig(provider='gemini', config={'model': 'models/text-embedding-004'}),
    history_db_path='mem0_history.db'
)
m = Memory(config=custom_config)

messages = [
    {"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
    {"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
    {"role": "user", "content": "I'm not a big fan of thriller movies but I love sci-fi movies."},
    {"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
]
m.add(messages, user_id="alice", metadata={"category": "movies"})

raises this

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[3], line 17
      9 m = Memory(config=custom_config)
     11 messages = [
     12     {"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
     13     {"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
     14     {"role": "user", "content": "I'm not a big fan of thriller movies but I love sci-fi movies."},
     15     {"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
     16 ]
---> 17 m.add(messages, user_id="alice", metadata={"category": "movies"})

File d:\Python\mem0\mem0\memory\main.py:167, in Memory.add(self, messages, user_id, agent_id, run_id, metadata, filters, infer, memory_type, prompt)
    163     future2 = executor.submit(self._add_to_graph, messages, filters)
    165     concurrent.futures.wait([future1, future2])
--> 167     vector_store_result = future1.result()
    168     graph_result = future2.result()
    170 if self.api_version == "v1.0":

File ~\AppData\Local\Programs\Python\Python313\Lib\concurrent\futures\_base.py:449, in Future.result(self, timeout)
    447     raise CancelledError()
    448 elif self._state == FINISHED:
--> 449     return self.__get_result()
    451 self._condition.wait(timeout)
    453 if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]:

File ~\AppData\Local\Programs\Python\Python313\Lib\concurrent\futures\_base.py:401, in Future.__get_result(self)
    399 if self._exception:
    400     try:
--> 401         raise self._exception
    402     finally:
    403         # Break a reference cycle with the exception in self._exception
    404         self = None

File ~\AppData\Local\Programs\Python\Python313\Lib\concurrent\futures\thread.py:59, in _WorkItem.run(self)
     56     return
     58 try:
---> 59     result = self.fn(*self.args, **self.kwargs)
     60 except BaseException as exc:
     61     self.future.set_exception(exc)

File d:\Python\mem0\mem0\memory\main.py:226, in Memory._add_to_vector_store(self, messages, metadata, filters, infer)
    224 messages_embeddings = self.embedding_model.embed(new_mem, "add")
    225 new_message_embeddings[new_mem] = messages_embeddings
--> 226 existing_memories = self.vector_store.search(
    227     query=new_mem,
    228     vectors=messages_embeddings,
    229     limit=5,
    230     filters=filters,
    231 )
    232 for mem in existing_memories:
    233     retrieved_old_memory.append({"id": mem.id, "text": mem.payload["data"]})

File d:\Python\mem0\mem0\vector_stores\qdrant.py:144, in Qdrant.search(self, query, vectors, limit, filters)
    131 """
    132 Search for similar vectors.
    133 
   (...)    141     list: Search results.
    142 """
    143 query_filter = self._create_filter(filters) if filters else None
--> 144 hits = self.client.query_points(
    145     collection_name=self.collection_name,
    146     query=vectors,
    147     query_filter=query_filter,
    148     limit=limit,
    149 )
    150 return hits.points

File d:\Python\mem0\.venv\Lib\site-packages\qdrant_client\qdrant_client.py:558, in QdrantClient.query_points(self, collection_name, query, using, prefetch, query_filter, search_params, limit, offset, with_payload, with_vectors, score_threshold, lookup_from, consistency, shard_key_selector, timeout, **kwargs)
    553     query = self._embed_models(query, is_query=True) if query is not None else None
    554     prefetch = (
    555         self._embed_models(prefetch, is_query=True) if prefetch is not None else None
    556     )
--> 558 return self._client.query_points(
    559     collection_name=collection_name,
    560     query=query,
    561     prefetch=prefetch,
    562     query_filter=query_filter,
    563     search_params=search_params,
    564     limit=limit,
    565     offset=offset,
    566     with_payload=with_payload,
    567     with_vectors=with_vectors,
    568     score_threshold=score_threshold,
    569     using=using,
    570     lookup_from=lookup_from,
    571     consistency=consistency,
    572     shard_key_selector=shard_key_selector,
    573     timeout=timeout,
    574     **kwargs,
    575 )

File d:\Python\mem0\.venv\Lib\site-packages\qdrant_client\local\qdrant_local.py:466, in QdrantLocal.query_points(self, collection_name, query, using, prefetch, query_filter, search_params, limit, offset, with_payload, with_vectors, score_threshold, lookup_from, **kwargs)
    463     query_filter = ignore_mentioned_ids_filter(query_filter, list(mentioned_ids))
    465 prefetch = self._resolve_prefetches_input(prefetch, collection_name)
--> 466 return collection.query_points(
    467     query=query,
    468     prefetch=prefetch,
    469     query_filter=query_filter,
    470     using=using,
    471     score_threshold=score_threshold,
    472     limit=limit,
    473     offset=offset or 0,
    474     with_payload=with_payload,
    475     with_vectors=with_vectors,
    476 )

File d:\Python\mem0\.venv\Lib\site-packages\qdrant_client\local\local_collection.py:703, in LocalCollection.query_points(self, query, prefetch, query_filter, limit, offset, with_payload, with_vectors, score_threshold, using, **kwargs)
    690     scored_points = self._merge_sources(
    691         sources=sources,
    692         query=query,
   (...)    699         score_threshold=score_threshold,
    700     )
    701 else:
    702     # It is a base query
--> 703     scored_points = self._query_collection(
    704         query=query,
    705         using=using,
    706         query_filter=query_filter,
    707         limit=limit,
    708         offset=offset,
    709         with_payload=with_payload,
    710         with_vectors=with_vectors,
    711         score_threshold=score_threshold,
    712     )
    714 return types.QueryResponse(points=scored_points)

File d:\Python\mem0\.venv\Lib\site-packages\qdrant_client\local\local_collection.py:840, in LocalCollection._query_collection(self, query, using, query_filter, limit, offset, with_payload, with_vectors, score_threshold)
    838     return [record_to_scored_point(record) for record in records[offset:]]
    839 elif isinstance(query, models.NearestQuery):
--> 840     return self.search(
    841         query_vector=(using, query.nearest),
    842         query_filter=query_filter,
    843         limit=limit,
    844         offset=offset,
    845         with_payload=with_payload,
    846         with_vectors=with_vectors,
    847         score_threshold=score_threshold,
    848     )
    849 elif isinstance(query, models.RecommendQuery):
    850     return self.recommend(
    851         positive=query.recommend.positive,
    852         negative=query.recommend.negative,
   (...)    860         score_threshold=score_threshold,
    861     )

File d:\Python\mem0\.venv\Lib\site-packages\qdrant_client\local\local_collection.py:573, in LocalCollection.search(self, query_vector, query_filter, limit, offset, with_payload, with_vectors, score_threshold)
    571 if isinstance(query_vector, np.ndarray):
    572     if len(query_vector.shape) == 1:
--> 573         scores = calculate_distance(query_vector, vectors, distance)
    574     else:
    575         scores = calculate_multi_distance(query_vector, vectors, distance)

File d:\Python\mem0\.venv\Lib\site-packages\qdrant_client\local\distances.py:152, in calculate_distance(query, vectors, distance_type)
    149 assert not np.isnan(query).any(), "Query vector must not contain NaN"
    151 if distance_type == models.Distance.COSINE:
--> 152     return cosine_similarity(query, vectors)
    153 elif distance_type == models.Distance.DOT:
    154     return dot_product(query, vectors)

File d:\Python\mem0\.venv\Lib\site-packages\qdrant_client\local\distances.py:94, in cosine_similarity(query, vectors)
     92     query_norm = np.linalg.norm(query)
     93     query /= np.where(query_norm != 0.0, query_norm, EPSILON)
---> 94     return np.dot(vectors, query)
     96 query_norm = np.linalg.norm(query, axis=-1)[:, np.newaxis]
     97 query /= np.where(query_norm != 0.0, query_norm, EPSILON)

ValueError: shapes (0,1536) and (768,) not aligned: 1536 (dim 1) != 768 (dim 0)

renanmoretto avatar Apr 13 '25 19:04 renanmoretto

@renanmoretto Can you specify embedding_model_dims to 768. The model you are using doesn't support 1536 dimensions and by default it takes 1536.

parshvadaftari avatar Apr 14 '25 06:04 parshvadaftari

@renanmoretto you can actually use this embedding model of gemini and specify the shape to 1536, it will not throw any errors. ` config = {

"embedder": {
    "provider": "gemini",
    "config": {
        "model": "models/gemini-embedding-exp-03-07",
        "embedding_dims": 1536
    }
}

}

`

Image

hacktivtools avatar Apr 14 '25 13:04 hacktivtools

worked with config={'model': 'models/gemini-embedding-exp-03-07', 'embedding_dims': 1536} but based on google docs shouldnt it also work with 768 and 3072 dims? getting an error on these source: https://ai.google.dev/gemini-api/docs/models#gemini-embedding

also for the text-embedding-004 model i just followed the docs here: https://docs.mem0.ai/components/embedders/models/gemini#config it defaults to 768 based on docs (https://ai.google.dev/gemini-api/docs/models#text-embedding), text-embedding-004 has dim size of 768, so shouldnt this also work? config={'model': 'models/text-embedding-004', 'embedding_dims': 768} it does not, though

renanmoretto avatar Apr 14 '25 14:04 renanmoretto

@renanmoretto i delete the collection and recreated the collection with embedding_dims:768 ,seems working now

unizhu avatar May 05 '25 03:05 unizhu

Closing as it's been fixed.

parshvadaftari avatar Aug 13 '25 17:08 parshvadaftari