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