由于使用了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 = 1for 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());// 词级 转 句级 ,采用meanfloat[] 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;}