由于使用了QAnything 本地知识库应答平台
内部已集成Embedding 文本向量化服务,因此不在单独部署。
基于 transformers
如果需要单独部署,可以参看 BCEmbedding/README_zh.md at master · netease-youdao/BCEmbedding · GitHub
从启动脚本中可以看出,集合多个服务,其中就包括embedding
其中embedding服务路径
qanything_kernel/dependent_server/embedding_server
在启动的容器中可以查看对应的模型配置
/root/models/linux_onnx/embedding_model_configs_v0.0.1
1、http调用
调用地址 http://0.0.0.0:9001/embedding
入参格式
{
"texts": "使用QAnything平台"
}
返回格式:
输入的每个汉字、字母、数字、符号等都会形成一个768向量维度的float数组
[
[0.002994537353515625,...],
[-0.00853729248046875,...],
[0.002994537353515625,...],
[0.002994537353515625,...],
[-0.00853729248046875, ...]
]
2、优化代码
执行结果速度有点慢,需要10多秒。内部将每个字符拆分,循环调用
修改 embedding_async_backend.py 文件
@get_time_async
async def embed_documents_async(self, texts):
futures = []
# 设置mini_batch=1,每次处理1个文本
mini_batch = 1
for i in range(0, len(texts), mini_batch):
future = asyncio.Future()
futures.append(future)
await self.queue.put((texts[i:i + mini_batch], future))
results = await asyncio.gather(*futures)
return [item for sublist in results for item in sublist]
改造代码
改造后执行耗时500ms。
@get_time_async
async def embed_documents_async_all(self, texts):
future = asyncio.Future()
futures.append(future)
await self.queue.put((texts, future))
results = await asyncio.gather(*futures)
return results
前后两次的向量结果存在不一致问题
经测试发现,相同的字在不同文本中的向量结果一致
使用静态词嵌入模型(如 Word2Vec 或 GloVe)时。模型为每个词生成唯一的固定向量,不考虑上下文
3、词向量转句级向量
本质上属于平均向量
private static final float[] EMPTY_VECTOR = new float[0];
List<? extends float[]> vectors = JSONUtil.toList(body, EMPTY_VECTOR.getClass());
// 词级 转 句级 ,采用mean
float[] result = vectors.get(0);
for (int i = 1; i < vectors.size(); i++) {
float[] item = vectors.get(i);
for (int t = 0; t < result.length; t++) {
result[t] = result[t] + item[t];
}
}
int len = vectors.size();
for (int i = 0; i < result.length; i++) {
result[i] = result[i] / len;
}