CPU-based brute force computation using scipy.sparse
(vectors, query_vectors, dimension, top_k=10)
| 218 | |
| 219 | |
| 220 | def _compute_brute_force_cpu(vectors, query_vectors, dimension, top_k=10): |
| 221 | """CPU-based brute force computation using scipy.sparse""" |
| 222 | from scipy.sparse import csr_matrix as cpu_csr_matrix |
| 223 | |
| 224 | results = [] |
| 225 | n_vectors = len(vectors) |
| 226 | print("Building dataset sparse matrix on CPU...") |
| 227 | |
| 228 | # Build dataset matrix |
| 229 | data_list = [] |
| 230 | indices_list = [] |
| 231 | indptr = [0] |
| 232 | |
| 233 | for vec in tqdm(vectors): |
| 234 | data_list.extend(vec["values"]) |
| 235 | indices_list.extend(vec["indices"]) |
| 236 | indptr.append(len(data_list)) |
| 237 | |
| 238 | A = cpu_csr_matrix((data_list, indices_list, indptr), shape=(n_vectors, dimension)) |
| 239 | |
| 240 | print("Computing similarities...") |
| 241 | for i, query in enumerate(tqdm(query_vectors)): |
| 242 | # Build query vector |
| 243 | q_data = query["values"] |
| 244 | q_indices = query["indices"] |
| 245 | q_indptr = [0, len(q_data)] |
| 246 | |
| 247 | Q = cpu_csr_matrix((q_data, q_indices, q_indptr), shape=(1, dimension)) |
| 248 | |
| 249 | # Compute dot products |
| 250 | scores = A.dot(Q.T).toarray().flatten() |
| 251 | |
| 252 | # Get top-k |
| 253 | top_indices = np.argpartition(scores, -top_k)[-top_k:] |
| 254 | top_indices = top_indices[np.argsort(scores[top_indices])[::-1]] |
| 255 | |
| 256 | top_results = [] |
| 257 | for idx in top_indices: |
| 258 | top_results.append({"id": vectors[idx]["id"], "score": float(scores[idx])}) |
| 259 | |
| 260 | results.append({"query_id": query["id"], "top_results": top_results}) |
| 261 | |
| 262 | return results |
| 263 | |
| 264 | |
| 265 | def _compute_brute_force_gpu(vectors, query_vectors, dimension, top_k=10): |
no test coverage detected