update
This commit is contained in:
parent
39ff8a07a9
commit
0ff38ffe8c
92
README.md
92
README.md
@ -1,5 +1,3 @@
|
|||||||
<img src="web/public/home.png" style="border-radius: 16px; margin: 0 auto; max-height: 400px; display: block;"/>
|
|
||||||
|
|
||||||
<h1 style="text-align: center">Yuxi (语析) </h1>
|
<h1 style="text-align: center">Yuxi (语析) </h1>
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
@ -7,17 +5,60 @@
|
|||||||
|
|
||||||
## 预览
|
## 预览
|
||||||
|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
## 准备
|
## 准备
|
||||||
|
|
||||||
1. 提供 API 服务商的 API_KEY,并放置在 `src/.env` 文件中,参考 `src/.env.template`。默认使用的是智谱AI。需要配置 `ZHIPUAI_API_KEY=<ZHIPU_KEY>`。
|
提供 API 服务商的 API_KEY,并放置在 `src/.env` 文件中,参考 `src/.env.template`。默认使用的是智谱AI。需要配置 `ZHIPUAI_API_KEY=<ZHIPUAI_API_KEY>`。
|
||||||
2. 配置 python 环境 `pip install -r requirements.txt`,python 版本应当小于 `3.12`。
|
|
||||||
3. 前端 UI 部分,需要安装 Node.js 环境,参考:[Download Node.js](https://nodejs.org/en/download/package-manager)。
|
|
||||||
|
|
||||||
|
## Dockers 启动
|
||||||
|
|
||||||
|
**提醒**:此部分暂时依赖于前端打包之后的内容(后面考虑更新),同时会自动启动 neo4j 图数据库。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker-compose -f docker/docker-compose.dev.yml up --build
|
||||||
|
```
|
||||||
|
|
||||||
|
下面的这些容器都会启动:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
[+] Running 7/7
|
||||||
|
✔ Network docker_app-network Created
|
||||||
|
✔ Container graph-dev Started
|
||||||
|
✔ Container milvus-etcd-dev Started
|
||||||
|
✔ Container milvus-minio-dev Started
|
||||||
|
✔ Container milvus-standalone-dev Started
|
||||||
|
✔ Container api-dev Started
|
||||||
|
✔ Container web-dev Started
|
||||||
|
```
|
||||||
|
|
||||||
|
关闭 docker 服务:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker-compose -f docker/docker-compose.dev.yml down
|
||||||
|
```
|
||||||
|
|
||||||
|
如果需要使用到本地模型,比如向量模型或者重排序模型,则需要将环境变量中设置的 `MODEL_ROOT_DIR` 做映射,比如本地模型都是存放在 `/hdd/models` 里面,则需要在 `docker-compose.yml` 中添加:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
services:
|
||||||
|
# 后端服务
|
||||||
|
backend:
|
||||||
|
image: pytorch/pytorch:2.4.1-cuda11.8-cudnn9-runtime # 或者您可以自定义 Python 基础镜像
|
||||||
|
container_name: backend
|
||||||
|
working_dir: /app
|
||||||
|
volumes:
|
||||||
|
- ./src:/app/src # 映射源代码
|
||||||
|
- ./requirements.txt:/app/requirements.txt
|
||||||
|
- ./saves:/app/saves
|
||||||
|
- /hdd/models:/hdd/models # <=== 修改这里
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
##
|
||||||
|
|
||||||
|
1. 配置 python 环境 `pip install -r requirements.txt`,python 版本应当小于 `3.12`。
|
||||||
|
2. 前端 UI 部分,需要安装 Node.js 环境,参考:[Download Node.js](https://nodejs.org/en/download/package-manager)。
|
||||||
|
|
||||||
**如果不启用知识库,可以仅安装下面的依赖**
|
**如果不启用知识库,可以仅安装下面的依赖**
|
||||||
|
|
||||||
@ -50,11 +91,13 @@ docker compose up -d
|
|||||||
|
|
||||||
## 启动
|
## 启动
|
||||||
|
|
||||||
|
推荐使用 docker 启动
|
||||||
|
|
||||||
### 1. 手动启动
|
### 1. 手动启动
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 后端部分
|
# 后端部分
|
||||||
python -m src.api
|
python -m src.main
|
||||||
|
|
||||||
# 前端部分
|
# 前端部分
|
||||||
cd web
|
cd web
|
||||||
@ -72,30 +115,9 @@ bash run.sh
|
|||||||
|
|
||||||
### 3. Docker 启动
|
### 3. Docker 启动
|
||||||
|
|
||||||
**提醒**:此部分暂时依赖于前端打包之后的内容(后面考虑更新),同时会自动启动 neo4j 图数据库。
|
## Changelog
|
||||||
|
|
||||||
```bash
|
- 2024.10.12 后端修改为 FastAPI,并添加了 Milnvs 的独立部署。
|
||||||
docker compose up --build
|
|
||||||
```
|
|
||||||
|
|
||||||
如果需要使用到本地模型,比如向量模型或者重排序模型,则需要将环境变量中设置的 `MODEL_ROOT_DIR` 做映射,比如本地模型都是存放在 `/hdd/models` 里面,则需要在 `docker-compose.yml` 中添加:
|
|
||||||
|
|
||||||
```yml
|
|
||||||
services:
|
|
||||||
# 后端服务
|
|
||||||
backend:
|
|
||||||
image: pytorch/pytorch:2.4.1-cuda11.8-cudnn9-runtime # 或者您可以自定义 Python 基础镜像
|
|
||||||
container_name: backend
|
|
||||||
working_dir: /app
|
|
||||||
volumes:
|
|
||||||
- ./src:/app/src # 映射源代码
|
|
||||||
- ./requirements.txt:/app/requirements.txt
|
|
||||||
- ./saves:/app/saves
|
|
||||||
- /hdd/models:/hdd/models # <=== 修改这里
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
**提醒**:启动 docker 之后,如果需要进行调试的时候,务必先停掉 docker (在项目路径下,使用 `docker compose down`),然后再运行 `bash run.sh`,不然会出现端口冲突。这是由于没有单独设置生产环境和开发环境,这个以后再说。
|
|
||||||
|
|
||||||
## 其余脚本
|
## 其余脚本
|
||||||
|
|
||||||
|
|||||||
25
scripts/init.sh
Normal file
25
scripts/init.sh
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 检查是否提供了 API_KEY 参数
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
echo "请提供 API_KEY。"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 获取当前目录路径
|
||||||
|
CURRENT_DIR=$(pwd)
|
||||||
|
|
||||||
|
# 如果 src 目录不存在则创建
|
||||||
|
if [! -d "${CURRENT_DIR}/src" ]; then
|
||||||
|
mkdir -p "${CURRENT_DIR}/src"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 如果.env 文件不存在,则从.env.template 复制一份创建
|
||||||
|
if [! -f "${CURRENT_DIR}/src/.env" ]; then
|
||||||
|
cp "${CURRENT_DIR}/src/.env.template" "${CURRENT_DIR}/src/.env"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 将 API_KEY 写入.env 文件
|
||||||
|
echo "ZHIPUAI_API_KEY=$1" > "${CURRENT_DIR}/src/.env"
|
||||||
|
|
||||||
|
echo "API_KEY 已成功写入 src/.env 文件。"
|
||||||
@ -6,12 +6,12 @@ if [ -z "$1" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$1" = "llama" ]; then
|
if [ "$1" = "llama" ]; then
|
||||||
CUDA_VISIBLE_DEVICES=0 python -m vllm.entrypoints.openai.api_server \
|
python -m vllm.entrypoints.openai.api_server \
|
||||||
--model="/hdd/zwj/models/meta-llama/$MODEL" \
|
--model="/hdd/zwj/models/meta-llama/Meta-Llama-3-8B-Instruct" \
|
||||||
--tensor-parallel-size 1 \
|
--tensor-parallel-size 2 \
|
||||||
--trust-remote-code \
|
--trust-remote-code \
|
||||||
--device auto \
|
--device auto \
|
||||||
--gpu-memory-utilization 0.98 \
|
--gpu-memory-utilization 0.8 \
|
||||||
--dtype half \
|
--dtype half \
|
||||||
--served-model-name "$1" \
|
--served-model-name "$1" \
|
||||||
--host 0.0.0.0 \
|
--host 0.0.0.0 \
|
||||||
|
|||||||
@ -170,6 +170,7 @@ class GraphDatabase:
|
|||||||
|
|
||||||
def jsonl_file_add_entity(self, file_path, kgdb_name='neo4j'):
|
def jsonl_file_add_entity(self, file_path, kgdb_name='neo4j'):
|
||||||
self.status = "processing"
|
self.status = "processing"
|
||||||
|
kgdb_name = kgdb_name or 'neo4j'
|
||||||
self.use_database(kgdb_name) # 切换到指定数据库
|
self.use_database(kgdb_name) # 切换到指定数据库
|
||||||
|
|
||||||
def read_triples(file_path):
|
def read_triples(file_path):
|
||||||
|
|||||||
@ -7,10 +7,6 @@ from src.utils.logging_config import setup_logger
|
|||||||
|
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
os.environ["ZHIPUAI_API_KEY"] = "270ea71e9560c0ff406acbcdd48bfd97.e3XOMdWKuZb7Q1Sk"
|
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
app.include_router(router)
|
app.include_router(router)
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,6 @@
|
|||||||
|`dashscope`(阿里) | `qwen-max-latest` | `DASHSCOPE_API_KEY`|
|
|`dashscope`(阿里) | `qwen-max-latest` | `DASHSCOPE_API_KEY`|
|
||||||
|`deepseek`|`deepseek-chat`|`DEEPSEEK_API_KEY`|
|
|`deepseek`|`deepseek-chat`|`DEEPSEEK_API_KEY`|
|
||||||
|`siliconflow` | `meta-llama/Meta-Llama-3.1-8B-Instruct` | `SILICONFLOW_API_KEY`|
|
|`siliconflow` | `meta-llama/Meta-Llama-3.1-8B-Instruct` | `SILICONFLOW_API_KEY`|
|
||||||
|`vllm`|`vllm`|`VLLM_API_KEY`, `VLLM_API_BASE`|
|
|
||||||
|
|
||||||
vllm 的具体配置项可以参考[这里](https://docs.vllm.ai/en/latest/serving/openai_compatible_server.html#named-arguments), 部署参考脚本:
|
vllm 的具体配置项可以参考[这里](https://docs.vllm.ai/en/latest/serving/openai_compatible_server.html#named-arguments), 部署参考脚本:
|
||||||
|
|
||||||
|
|||||||
@ -35,7 +35,7 @@ async def create_database(
|
|||||||
return database_info
|
return database_info
|
||||||
|
|
||||||
@data.delete("/")
|
@data.delete("/")
|
||||||
async def delete_database(db_id: str = Body(...)):
|
async def delete_database(db_id):
|
||||||
logger.debug(f"Delete database {db_id}")
|
logger.debug(f"Delete database {db_id}")
|
||||||
startup.dbm.delete_database(db_id)
|
startup.dbm.delete_database(db_id)
|
||||||
return {"message": "删除成功"}
|
return {"message": "删除成功"}
|
||||||
@ -114,7 +114,7 @@ async def get_graph_nodes(kgdb_name: str, num: int):
|
|||||||
return {"result": startup.retriever.format_general_results(result), "message": "success"}
|
return {"result": startup.retriever.format_general_results(result), "message": "success"}
|
||||||
|
|
||||||
@data.post("/graph/add")
|
@data.post("/graph/add")
|
||||||
async def add_graph_entity(kgdb_name: str = Body(...), file_path: str = Body(...)):
|
async def add_graph_entity(file_path: str = Body(...), kgdb_name: Optional[str] = Body(None)):
|
||||||
if not startup.config.enable_knowledge_graph:
|
if not startup.config.enable_knowledge_graph:
|
||||||
raise HTTPException(status_code=400, detail="Knowledge graph is not enabled")
|
raise HTTPException(status_code=400, detail="Knowledge graph is not enabled")
|
||||||
|
|
||||||
|
|||||||
@ -334,8 +334,11 @@ const updateStatus = (id, status) => {
|
|||||||
console.error('Message not found')
|
console.error('Message not found')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.refs.knowledge_base.results.length > 0) {
|
if (message.refs && message.refs.knowledge_base.results.length > 0) {
|
||||||
message.groupedResults = message.refs.knowledge_base.results.reduce((acc, result) => {
|
|
||||||
|
message.groupedResults = message.refs.knowledge_base.results
|
||||||
|
.filter(result => result.file && result.file.filename)
|
||||||
|
.reduce((acc, result) => {
|
||||||
const { filename } = result.file;
|
const { filename } = result.file;
|
||||||
console.log(acc, result, filename)
|
console.log(acc, result, filename)
|
||||||
if (!acc[filename]) {
|
if (!acc[filename]) {
|
||||||
@ -415,12 +418,13 @@ const fetchChatResponse = (user_input, cur_res_id) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
return readChunk();
|
return readChunk();
|
||||||
|
isStreaming.value = false;
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
updateStatus(cur_res_id, "error");
|
updateStatus(cur_res_id, "error");
|
||||||
isStreaming.value = false;
|
isStreaming.value = false;
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新后的 sendMessage 函数
|
// 更新后的 sendMessage 函数
|
||||||
|
|||||||
@ -362,10 +362,10 @@ const deleteDatabse = () => {
|
|||||||
cancelText: '取消',
|
cancelText: '取消',
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
state.lock = true
|
state.lock = true
|
||||||
fetch('/api/data/', {
|
fetch(`/api/data/?db_id=${databaseId.value}`, {
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json" // 添加 Content-Type 头
|
"Content-Type": "application/json"
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
db_id: databaseId.value
|
db_id: databaseId.value
|
||||||
@ -431,6 +431,9 @@ const formatRelativeTime = (timestamp) => {
|
|||||||
|
|
||||||
const getDatabaseInfo = () => {
|
const getDatabaseInfo = () => {
|
||||||
const db_id = databaseId.value
|
const db_id = databaseId.value
|
||||||
|
if (!db_id) {
|
||||||
|
return
|
||||||
|
}
|
||||||
state.lock = true
|
state.lock = true
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
fetch(`/api/data/info?db_id=${db_id}`, {
|
fetch(`/api/data/info?db_id=${db_id}`, {
|
||||||
|
|||||||
@ -135,7 +135,7 @@
|
|||||||
<a-input v-model:value="customModel.name" />
|
<a-input v-model:value="customModel.name" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="API Base" name="api_base" :rules="[{ required: true, message: '请输入API Base' }]">
|
<a-form-item label="API Base" name="api_base" :rules="[{ required: true, message: '请输入API Base' }]">
|
||||||
<a-input v-model:value="customModel.api_base" type="password"/>
|
<a-input v-model:value="customModel.api_base"/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="API KEY" name="api_key">
|
<a-form-item label="API KEY" name="api_key">
|
||||||
<a-input v-model:value="customModel.api_key" autocomplete="off"/>
|
<a-input v-model:value="customModel.api_key" autocomplete="off"/>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user