chroma-core / chroma

the AI-native open-source embedding database
https://www.trychroma.com/
Apache License 2.0
14.44k stars 1.2k forks source link

[Bug]: Doesn't return results with shortest distances unless n_results is sufficiently large #1205

Open zephyrprime opened 11 months ago

zephyrprime commented 11 months ago

What happened?

Chromadb will fail to return the embeddings with the closest results unless I set n_results to a sufficiently large number.

I am using version 0.4.13 but this problem has happened with every version I've used. I find that basic querying of the db is buggy and does not return the highest scoring results if you don't have n_results set to a sufficiently big number. For example, if I perform this search with n_results=27, it will fail to find the correct highest scoring embeddings. I have ~44000 pieces of text in my DB.

collection.query( query_texts="A description of 'visitor q'", n_results=27 )

results: {'ids': [['53593', '397', '54214', ...]], 'distances': [[0.832878589630127, 0.857905924320221, 0.8623576164245605, ...]], 'metadatas': [[{'release date': '2005-11-18', 'title': 'Unveiled'}, {'release date': '1935-03-08', 'title': 'Naughty Marietta'}, {'release date': '1997-05-09', 'title': 'Welcome To Sarajevo'}, ...

However, if I search with n_results=28 or greater, it will return the correct results. collection.query( query_texts="A description of 'visitor q'", n_results=28 )

Results: {'ids': [['11917', '11918', '11919', ...]], 'distances': [[0.6459631323814392, 0.6608277559280396, 0.665003776550293, ...]], 'metadatas': [[{'release date': '2001-03-17', 'title': 'Visitor Q'}, {'release date': '2001-03-17', 'title': 'Visitor Q'}, {'release date': '2001-03-17', 'title': 'Visitor Q'}, {'title': 'The Visitors'}, ... I am using "BAAI/bge-large-en-v1.5" and sentence transformers. However this happens with other the Instructor models too. I am using the default distance function and not setting a custom value for that.

This doesn't happen with all queries. Only some queries have this problem. This is a pretty big problem for me since it's giving me wrong results with some queries. Seems like a bug to me.

Versions

0.4.13, python 3.11.3, windows 11. I also had this happen on a debian 11 server I used.

Relevant log output

No response

HammadB commented 11 months ago

Have you tried altering the hnsw parameters of your index? They control the quality of the search, setting n_results to be large implictly increases the search_ef parameter which makes your search more exhaustive. You can set hnsw:M/search_ef/construction_ef when you create the collection metadata.

zephyrprime commented 11 months ago

I am very surprised that the search isn't always exhaustive already. I have now read that there is a performance problem that inhibits exhaustive search. How can I set the hnsw parameters? What are the default parameters being used? I cannot find any documentation in chromadb except for the hnsw:space parameter which doesn't seem to be the issue.

HammadB commented 11 months ago

Why would you expect it to be exhaustive? Chroma uses an approximate nearest neighbors index which will prune the candidates it searches.

https://github.com/chroma-core/chroma/blob/fc4c8b547444efafa8ddf75fbd53a9b8e1a7eabe/chromadb/test/test_api.py#L1060

This is an example of setting the params.

Sorry the documentation here is sparse, we want to make the custom index parameter definition better by strongly typing it. But we should add docs in the interim!

pmeier commented 10 months ago

We were bitten by this as well. Documentation on the hnsw parameters would be much appreciated.

pmeier commented 10 months ago

In the mean time, here is a list of all available parameters

https://github.com/chroma-core/chroma/blob/cdcafc8886cfae0e1f04d0c9d5ffec4339c16aa4/chromadb/segment/impl/vector/hnsw_params.py#L10-L23

and the corresponding defaults

https://github.com/chroma-core/chroma/blob/cdcafc8886cfae0e1f04d0c9d5ffec4339c16aa4/chromadb/segment/impl/vector/hnsw_params.py#L55-L63

https://github.com/chroma-core/chroma/blob/cdcafc8886cfae0e1f04d0c9d5ffec4339c16aa4/chromadb/segment/impl/vector/hnsw_params.py#L79-L80

ha-sante commented 10 months ago

Damn - How we all come to meet here 😂- same issue as well @pmeier thank you for the code guides.

falk0n commented 10 months ago

In the mean time, here is a list of all available parameters

https://github.com/chroma-core/chroma/blob/cdcafc8886cfae0e1f04d0c9d5ffec4339c16aa4/chromadb/segment/impl/vector/hnsw_params.py#L10-L23

and the corresponding defaults

https://github.com/chroma-core/chroma/blob/cdcafc8886cfae0e1f04d0c9d5ffec4339c16aa4/chromadb/segment/impl/vector/hnsw_params.py#L55-L63

https://github.com/chroma-core/chroma/blob/cdcafc8886cfae0e1f04d0c9d5ffec4339c16aa4/chromadb/segment/impl/vector/hnsw_params.py#L79-L80

How do the hnsw parameters relate to the parameters described in https://arxiv.org/abs/1603.09320 ?

Vermeille commented 6 months ago

Why would you expect it to be exhaustive? Yes right? Why would you expect a search function to correctly search indeed? Seriously this answer would be extremely funny if it weren't this infuriating.

pilotofbalance commented 6 months ago

hey guys, if someone found a best one for "semantic search" pls post here your metadata index configuration. I want chroma will have better documentation in the future..

wilsonweb commented 4 months ago

And for those of us that speak JavaScript, I took these parameters to values similar to hnswlib

       collection = await client.createCollection({
            name: "items",
            embeddingFunction: embedder,
            metadata: {
                "hnsw:space": "l2", "hnsw:M": 16, "hnsw:construction_ef": 200 
            }, 
        });