1
chengxiao 2019-07-04 16:22:04 +08:00
250 维....这不是数据库能处理的吧?
|
2
lunaticus7 2019-07-04 16:33:33 +08:00
`但是从 DB 把数据拿到内存就需要 7 秒` 是指取 20000 * 250 向量?
特征向量为什么要存 mangoDB 嘛,这点量也没多少,直接塞内存,精度可以转成 np.float32 甚至 np.float16,能省很多内存,这些精度做检索够用 解决了了从数据库读特征向量的问题后,就可以优化检索计算了 大方向就是分级检索:先用低运算量低精度的 metirc (句向量的话直接 cosine 就行)快速检索出一个较大的候选集,然后在候选集内部再用正常的高精度低速 metirc 得出最终结果 懒得折腾可以直接上 fb 家的 faiss PS.你什么算法啊,20w 数据相似度居然要算 2s ? |
3
sunhk25 OP @lunaticus7
谢谢意见,7s 是指从数据库拿数据 现在就是简单的计算内积,20 万的话就要 1G 内存 250 * 20 * 10000 * 24 / (1024 * 1024) = 1144.4MB |
4
owenliang 2019-07-04 17:58:20 +08:00
不行就把计算摘出去,换个 c++/golang 做一下,1 秒内肯定没有问题。
|
5
necomancer 2019-07-04 22:56:28 +08:00 1
numpy 的 dot 和 einsum 都比较慢,你可以考虑用 numba 的 guvectorize
@guvectorize([(float64[:], float64[:], float64[:])], '(n),(n)->()', target='parallel') def my_inner_prod(a, b, ret): tmp1 = tmp2 = tmp3 = 0 for i in range(a.shape[0]): tmp1 += a[i] * b[i] tmp2 += a[i] * a[i] tmp3 += b[i] * b[i] ret[0] = tmp1 / (tmp2 * tmp3) ** 0.5 这个是 cos(theta),如果不除以模量则只要 tmp1 就可以了 可以快很多。只要向量维度是对齐的,比如 (100000,250) . (100000,250) -> (100000,) 或者(100000,250) . (1,250) -> (100000,) 降维是不是可以考虑 PCA? |
6
necomancer 2019-07-04 22:59:55 +08:00
In [29]: a = np.random.random((200000,250))
In [30]: my_inner_prod(a,a) Out[30]: array([1., 1., 1., ..., 1., 1., 1.]) In [31]: %timeit my_inner_prod(a,a) 49.3 ms ± 850 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) I7-3687u |
7
TobiahShaw 2019-07-05 12:00:39 +08:00
想降维的话可以用下 PCA,分析一下主成分试一下,可以提前计算相似度存在 kv 服务,用的时候直接取
|
8
ebingtel 2019-07-05 13:56:17 +08:00
1、 预计算,不要求实时性的话
2、用 redis 进行 bit 计算和存储 |
9
sunhk25 OP @ebingtel 正在调查用 memchached 还是 radis 呢。
Redis 做缓存,mongodb 做持久化,两者结合的话会不会好一点? |
10
ldyisbest 2021-12-23 23:30:49 +08:00
试试向量数据库 milvus
|