(improvement)(chat) Support loading local embedding models through the in-memory configuration method (#1201)
@@ -1,9 +1,7 @@
|
||||
package com.tencent.supersonic.common.service.impl;
|
||||
|
||||
import com.tencent.supersonic.common.service.EmbeddingService;
|
||||
import com.tencent.supersonic.common.util.ContextUtils;
|
||||
import dev.langchain4j.data.embedding.Embedding;
|
||||
import dev.langchain4j.model.embedding.BgeSmallZhEmbeddingModel;
|
||||
import dev.langchain4j.model.embedding.EmbeddingModel;
|
||||
import dev.langchain4j.store.embedding.EmbeddingMatch;
|
||||
import dev.langchain4j.store.embedding.EmbeddingQuery;
|
||||
@@ -24,7 +22,6 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -34,6 +31,9 @@ public class EmbeddingServiceImpl implements EmbeddingService {
|
||||
@Autowired
|
||||
private EmbeddingStoreFactory embeddingStoreFactory;
|
||||
|
||||
@Autowired
|
||||
private EmbeddingModel embeddingModel;
|
||||
|
||||
public synchronized void addCollection(String collectionName) {
|
||||
embeddingStoreFactory.create(collectionName);
|
||||
}
|
||||
@@ -41,7 +41,6 @@ public class EmbeddingServiceImpl implements EmbeddingService {
|
||||
@Override
|
||||
public void addQuery(String collectionName, List<EmbeddingQuery> queries) {
|
||||
EmbeddingStore embeddingStore = embeddingStoreFactory.create(collectionName);
|
||||
EmbeddingModel embeddingModel = getEmbeddingModel();
|
||||
for (EmbeddingQuery query : queries) {
|
||||
String question = query.getQuery();
|
||||
Embedding embedding = embeddingModel.embed(question).content();
|
||||
@@ -49,26 +48,15 @@ public class EmbeddingServiceImpl implements EmbeddingService {
|
||||
}
|
||||
}
|
||||
|
||||
private static EmbeddingModel getEmbeddingModel() {
|
||||
EmbeddingModel embeddingModel;
|
||||
try {
|
||||
embeddingModel = ContextUtils.getBean(EmbeddingModel.class);
|
||||
} catch (NoSuchBeanDefinitionException e) {
|
||||
embeddingModel = new BgeSmallZhEmbeddingModel();
|
||||
}
|
||||
return embeddingModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteQuery(String collectionName, List<EmbeddingQuery> queries) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RetrieveQueryResult> retrieveQuery(String collectionName, RetrieveQuery retrieveQuery, int num) {
|
||||
EmbeddingStore embeddingStore = embeddingStoreFactory.create(collectionName);
|
||||
EmbeddingModel embeddingModel = getEmbeddingModel();
|
||||
List<RetrieveQueryResult> results = new ArrayList<>();
|
||||
|
||||
EmbeddingStore embeddingStore = embeddingStoreFactory.create(collectionName);
|
||||
List<String> queryTextsList = retrieveQuery.getQueryTextsList();
|
||||
Map<String, String> filterCondition = retrieveQuery.getFilterCondition();
|
||||
for (String queryText : queryTextsList) {
|
||||
@@ -110,7 +98,7 @@ public class EmbeddingServiceImpl implements EmbeddingService {
|
||||
|
||||
private static Filter createCombinedFilter(Map<String, String> map) {
|
||||
Filter result = null;
|
||||
if (Objects.isNull(map)) {
|
||||
if (MapUtils.isEmpty(map)) {
|
||||
return null;
|
||||
}
|
||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package dev.langchain4j.inmemory.spring;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
class EmbeddingModelProperties {
|
||||
|
||||
private String modelName;
|
||||
private String modelPath;
|
||||
private String vocabularyPath;
|
||||
}
|
||||
@@ -3,7 +3,12 @@ package dev.langchain4j.inmemory.spring;
|
||||
|
||||
import static dev.langchain4j.inmemory.spring.Properties.PREFIX;
|
||||
|
||||
import dev.langchain4j.model.embedding.AllMiniLmL6V2QuantizedEmbeddingModel;
|
||||
import dev.langchain4j.model.embedding.BgeSmallZhEmbeddingModel;
|
||||
import dev.langchain4j.model.embedding.EmbeddingModel;
|
||||
import dev.langchain4j.model.embedding.S2OnnxEmbeddingModel;
|
||||
import dev.langchain4j.store.embedding.EmbeddingStoreFactory;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -13,9 +18,31 @@ import org.springframework.context.annotation.Configuration;
|
||||
@EnableConfigurationProperties(Properties.class)
|
||||
public class InMemoryAutoConfig {
|
||||
|
||||
public static final String BGE_SMALL_ZH = "bge-small-zh";
|
||||
public static final String ALL_MINILM_L6_V2 = "all-minilm-l6-v2-q";
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(PREFIX + ".embedding-store.file-path")
|
||||
EmbeddingStoreFactory milvusChatModel(Properties properties) {
|
||||
return new InMemoryEmbeddingStoreFactory(properties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(PREFIX + ".embedding-model.model-name")
|
||||
EmbeddingModel inMemoryEmbeddingModel(Properties properties) {
|
||||
EmbeddingModelProperties embeddingModelProperties = properties.getEmbeddingModel();
|
||||
String modelPath = embeddingModelProperties.getModelPath();
|
||||
String vocabularyPath = embeddingModelProperties.getVocabularyPath();
|
||||
if (StringUtils.isNotBlank(modelPath) && StringUtils.isNotBlank(vocabularyPath)) {
|
||||
return new S2OnnxEmbeddingModel(modelPath, vocabularyPath);
|
||||
}
|
||||
String modelName = embeddingModelProperties.getModelName();
|
||||
if (BGE_SMALL_ZH.equalsIgnoreCase(modelName)) {
|
||||
return new BgeSmallZhEmbeddingModel();
|
||||
}
|
||||
if (ALL_MINILM_L6_V2.equalsIgnoreCase(modelName)) {
|
||||
return new AllMiniLmL6V2QuantizedEmbeddingModel();
|
||||
}
|
||||
return new BgeSmallZhEmbeddingModel();
|
||||
}
|
||||
}
|
||||
@@ -14,4 +14,7 @@ public class Properties {
|
||||
|
||||
@NestedConfigurationProperty
|
||||
EmbeddingStoreProperties embeddingStore;
|
||||
|
||||
@NestedConfigurationProperty
|
||||
EmbeddingModelProperties embeddingModel;
|
||||
}
|
||||
@@ -108,7 +108,10 @@ langchain4j:
|
||||
# model-name: qwen-max-1201
|
||||
# embedding-model:
|
||||
# api-key: ${OPENAI_API_KEY:demo}
|
||||
|
||||
in-memory:
|
||||
embedding-model:
|
||||
model-name: bge-small-zh
|
||||
#modelPath: /data/model.onnx
|
||||
#vocabularyPath: /data/onnx_vocab.txt
|
||||
embedding-store:
|
||||
file-path: /tmp
|
||||
|
||||
@@ -108,5 +108,9 @@ langchain4j:
|
||||
# base-url: ${OPENAI_API_BASE:https://api.openai.com/v1}
|
||||
# api-key: ${OPENAI_API_KEY:demo}
|
||||
in-memory:
|
||||
embedding-model:
|
||||
model-name: bge-small-zh
|
||||
#modelPath: /data/model.onnx
|
||||
#vocabularyPath: /data/onnx_vocab.txt
|
||||
embedding-store:
|
||||
file-path: /tmp
|
||||
@@ -1 +0,0 @@
|
||||
preview.pro.ant.design
|
||||
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"/umi.css": "/webapp/umi.b2bea3a5.css",
|
||||
"/umi.js": "/webapp/umi.4ebb29c3.js",
|
||||
"/umi.woff2": "/webapp/static/iconfont.0ac2d58a.woff2",
|
||||
"/umi.ttf": "/webapp/static/iconfont.7ae6e4e0.ttf",
|
||||
"/umi.woff": "/webapp/static/iconfont.0de60a33.woff",
|
||||
"/umi.svg": "/webapp/static/cloudEditor.1a9aa2c1.svg",
|
||||
"/public/home_bg.png": "/webapp/home_bg.png",
|
||||
"/static/iconfont.svg?t=1659425018463": "/webapp/static/iconfont.92a3f736.svg",
|
||||
"/static/cloudEditor.svg": "/webapp/static/cloudEditor.1a9aa2c1.svg",
|
||||
"/static/iconfont.ttf?t=1659425018463": "/webapp/static/iconfont.7ae6e4e0.ttf",
|
||||
"/static/iconfont.woff?t=1659425018463": "/webapp/static/iconfont.0de60a33.woff",
|
||||
"/static/iconfont.woff2?t=1659425018463": "/webapp/static/iconfont.0ac2d58a.woff2",
|
||||
"/public/icons/icon-512x512.png": "/webapp/icons/icon-512x512.png",
|
||||
"/public/icons/icon-192x192.png": "/webapp/icons/icon-192x192.png",
|
||||
"/public/icons/icon-128x128.png": "/webapp/icons/icon-128x128.png",
|
||||
"/public/logo.svg": "/webapp/logo.svg",
|
||||
"/public/pro_icon.svg": "/webapp/pro_icon.svg",
|
||||
"/public/favicon.ico": "/webapp/favicon.ico",
|
||||
"/public/version.js": "/webapp/version.js",
|
||||
"/public/CNAME": "/webapp/CNAME",
|
||||
"/public/supersonic.config.json": "/webapp/supersonic.config.json"
|
||||
}
|
||||
|
Before Width: | Height: | Size: 551 B |
|
Before Width: | Height: | Size: 199 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 5.0 KiB |
@@ -1,34 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta
|
||||
http-equiv="Cache-Control"
|
||||
content="no-cache, no-store, must-revalidate"
|
||||
/>
|
||||
<meta http-equiv="Pragma" content="no-cache" />
|
||||
<meta http-equiv="Expires" content="0" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"
|
||||
/>
|
||||
<title>超音数(SuperSonic)</title>
|
||||
<link rel="icon" href="/webapp/favicon.ico" type="image/x-icon" />
|
||||
<meta name="app_version" content="2023-09-04 00:07:38" />
|
||||
<link rel="stylesheet" href="/webapp/umi.b2bea3a5.css" />
|
||||
<script>
|
||||
window.routerBase = "/webapp/";
|
||||
</script>
|
||||
<script>
|
||||
//! umi version: 3.5.41
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>Out-of-the-box mid-stage front/design solution!</noscript>
|
||||
|
||||
<div id="root"></div>
|
||||
<script src="/webapp/umi.4ebb29c3.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 44 18" class="design-iconfont" width="128" height="128"><path d="M24.7272727,4.26325641e-14 L33.5127273,17.4545455 L26.5345455,17.4545455 L21.1236364,6.70181818 L24.7272727,4.26325641e-14 Z M17.52,4.26325641e-14 L21.1236364,6.70181818 L15.7127273,17.4545455 L8.73090909,17.4545455 L17.52,4.26325641e-14 Z M41.5890909,12.6945455 L43.9818182,17.4545455 L35.0909091,17.4545455 L32.6981818,12.6945455 L41.5890909,12.6945455 Z M12.68,6.32 L7.08,17.4545455 L0.498181818,17.4545455 L6.09818182,6.32 L12.68,6.32 Z M38.4145455,6.32 L40.9090909,11.2727273 L32.0181818,11.2727273 L29.5272727,6.32 L38.4145455,6.32 Z M15.7890909,0.141818182 L13.3963636,4.89818182 L-3.55271368e-14,4.89818182 L2.39272727,0.141818182 L15.7890909,0.141818182 Z M35.2690909,0.141818182 L37.6654545,4.89818182 L28.7745455,4.89818182 L26.3818182,0.141818182 L35.2690909,0.141818182 Z" fill-rule="evenodd" fill="#1890ff"></path></svg>
|
||||
|
Before Width: | Height: | Size: 953 B |
@@ -1,5 +0,0 @@
|
||||
<svg width="42" height="42" xmlns="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<path fill="#070707" d="m6.717392,13.773912l5.6,0c2.8,0 4.7,1.9 4.7,4.7c0,2.8 -2,4.7 -4.9,4.7l-2.5,0l0,4.3l-2.9,0l0,-13.7zm2.9,2.2l0,4.9l1.9,0c1.6,0 2.6,-0.9 2.6,-2.4c0,-1.6 -0.9,-2.4 -2.6,-2.4l-1.9,0l0,-0.1zm8.9,11.5l2.7,0l0,-5.7c0,-1.4 0.8,-2.3 2.2,-2.3c0.4,0 0.8,0.1 1,0.2l0,-2.4c-0.2,-0.1 -0.5,-0.1 -0.8,-0.1c-1.2,0 -2.1,0.7 -2.4,2l-0.1,0l0,-1.9l-2.7,0l0,10.2l0.1,0zm11.7,0.1c-3.1,0 -5,-2 -5,-5.3c0,-3.3 2,-5.3 5,-5.3s5,2 5,5.3c0,3.4 -1.9,5.3 -5,5.3zm0,-2.1c1.4,0 2.2,-1.1 2.2,-3.2c0,-2 -0.8,-3.2 -2.2,-3.2c-1.4,0 -2.2,1.2 -2.2,3.2c0,2.1 0.8,3.2 2.2,3.2z" class="st0" id="Ant-Design-Pro"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 677 B |
|
Before Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 97 KiB |
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"env": ""
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
feVersion={commitId:"774ea83b7f7505d0711e3bf6cb31dd6a31dfbf30",updateTime:"Mon Sep 04 2023 00:07:35 GMT+0800 (China Standard Time)"};
|
||||