165 lines
6.2 KiB
Markdown
165 lines
6.2 KiB
Markdown
# 元炁 · 本地推理引擎
|
||
|
||
元炁(Yuánqì)是魂镜的**本地模型推理引擎**,纯 Python 实现,直接加载 GGUF / FlagEmbedding / transformers 模型进行本地推理,不依赖外部推理服务。
|
||
|
||
> 「元」即原始、根本;「炁」为道家万化之源的能量。——元炁为魂镜承载本地模型推理,提供内生智力。
|
||
|
||
---
|
||
|
||
## 架构概览
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
lingtai[灵台 · Backend]
|
||
yuanqi[元炁 · Local Inference Engine]
|
||
models[(models/ 目录)]
|
||
|
||
lingtai -->|POST /v1/chat/completions| yuanqi
|
||
lingtai -->|POST /v1/embeddings| yuanqi
|
||
lingtai -->|POST /v1/rerank| yuanqi
|
||
lingtai -->|GET /healthz| yuanqi
|
||
yuanqi -->|llama-cpp-python 直接加载| models
|
||
yuanqi -->|FlagEmbedding / transformers 直接加载| models
|
||
```
|
||
|
||
## 提供的 API
|
||
|
||
| 端点 | 能力 | 引擎 |
|
||
| --- | --- | --- |
|
||
| `POST /v1/chat/completions` | LLM 对话 & 多模态视觉理解 | `llama-cpp-python` |
|
||
| `POST /v1/embeddings` | 文本向量嵌入 | `FlagEmbedding`(BGE-M3) |
|
||
| `POST /v1/rerank` | 重排序(Reranker) | `transformers` CrossEncoder |
|
||
| `GET /healthz` | 健康检查 | — |
|
||
|
||
## 模型文件结构
|
||
|
||
所有模型统一放在项目根目录 `models/` 下,按子目录分类:
|
||
|
||
```text
|
||
models/
|
||
├── gguf/ # GGUF 格式 LLM + 多模态模型
|
||
│ ├── qwen2.5-7b-instruct-q4_k_m.gguf
|
||
│ ├── llama3.2-vision-11b-q4_k_m.gguf
|
||
│ └── llama3.2-vision-11b-mmproj-f16.gguf
|
||
├── FlagModel/ # FlagEmbedding 模型
|
||
│ └── bge-m3/ # BGE-M3 嵌入模型
|
||
└── transformers/ # transformers 交叉编码器
|
||
└── bge-reranker-v2-m3/ # 重排序模型
|
||
```
|
||
|
||
通过环境变量 `YUANQI_MODELS_DIR` 可覆盖模型根目录。
|
||
|
||
## 快速开始
|
||
|
||
```bash
|
||
# 1. 下载模型(任选需要的)
|
||
# LLM:
|
||
wget -P models/gguf/ https://hf.co/Qwen/Qwen2.5-7B-Instruct-GGUF/resolve/main/qwen2.5-7b-instruct-q4_k_m.gguf
|
||
# Embedding:
|
||
pip install huggingface-hub
|
||
huggingface-cli download BAAI/bge-m3 --local-dir models/FlagModel/bge-m3
|
||
# Reranker:
|
||
huggingface-cli download BAAI/bge-reranker-v2-m3 --local-dir models/transformers/bge-reranker-v2-m3
|
||
|
||
# 2. 启动元炁
|
||
cd yuanqi
|
||
uv venv -p 3.12
|
||
source .venv/bin/activate
|
||
# 安装全部依赖包括开发依赖
|
||
uv sync --all-extras
|
||
# 安装启动对应的所有依赖,不包括开发依赖
|
||
uv sync --extra all
|
||
uv run uvicorn src.main:app --reload --port 11434
|
||
|
||
# 3. 验证
|
||
curl http://localhost:11434/healthz
|
||
```
|
||
|
||
## 模型tokenizer验证
|
||
|
||
```bash
|
||
python -c 'from transformers import AutoTokenizer; t=AutoTokenizer.from_pretrained("/Users/chenxin/code/python/hunjing/models/FlagModel/bge-m3"); ids=t("你好世界").input_ids; print("len:",len(ids)); print("ids:",ids); print("tokens:",t.convert_ids_to_tokens(ids))'
|
||
len: 5
|
||
ids: [0, 6, 124084, 3221, 2]
|
||
tokens: ['<s>', '▁', '你好', '世界', '</s>']
|
||
|
||
python -c 'from transformers import AutoTokenizer; t=AutoTokenizer.from_pretrained("/Users/chenxin/code/python/hunjing/models/transformers/bge-reranker-v2-m3"); q="搜索查询"; docs=["文档A","文档B","文档C"]; [(print("\nDOC:",d),print("len:",len(t(q,d).input_ids)),print("ids:",t(q,d).input_ids),print("tokens:",t.convert_ids_to_tokens(t(q,d).input_ids))) for d in docs]'
|
||
|
||
DOC: 文档A
|
||
len: 11
|
||
ids: [0, 6, 63449, 115106, 2, 2, 6, 2564, 59529, 284, 2]
|
||
tokens: ['<s>', '▁', '搜索', '查询', '</s>', '</s>', '▁', '文', '档', 'A', '</s>']
|
||
|
||
DOC: 文档B
|
||
len: 11
|
||
ids: [0, 6, 63449, 115106, 2, 2, 6, 2564, 59529, 571, 2]
|
||
tokens: ['<s>', '▁', '搜索', '查询', '</s>', '</s>', '▁', '文', '档', 'B', '</s>']
|
||
|
||
DOC: 文档C
|
||
len: 11
|
||
ids: [0, 6, 63449, 115106, 2, 2, 6, 2564, 59529, 441, 2]
|
||
tokens: ['<s>', '▁', '搜索', '查询', '</s>', '</s>', '▁', '文', '档', 'C', '</s>']
|
||
```
|
||
|
||
## 配置
|
||
|
||
通过环境变量配置(详见 `.env.example`):
|
||
|
||
| 变量 | 默认值 | 说明 |
|
||
| --- | --- | --- |
|
||
| `YUANQI_HOST` | `0.0.0.0` | 监听地址 |
|
||
| `YUANQI_PORT` | `11434` | 监听端口 |
|
||
| `YUANQI_MODELS_DIR` | `../models` | 模型文件根目录 |
|
||
| `YUANQI_LLM_MODEL_PATH` | 自动扫描 `models/gguf/` | GGUF 模型路径 |
|
||
| `YUANQI_EMBEDDING_MODEL` | `BAAI/bge-m3` | Embedding 模型(HF名或本地路径) |
|
||
| `YUANQI_RERANKER_MODEL` | `BAAI/bge-reranker-v2-m3` | Reranker 模型(HF名或本地路径) |
|
||
| `YUANQI_VISION_MODEL_PATH` | 自动扫描 `models/gguf/` | 多模态 GGUF 路径 |
|
||
| `YUANQI_DEVICE` | `cpu` | 推理设备:cpu / cuda / mps |
|
||
| `YUANQI_LLM_MAX_TOKENS` | `2048` | 最大生成 Token |
|
||
| `YUANQI_LLM_TEMPERATURE` | `0.7` | 生成温度 |
|
||
| `YUANQI_LLM_CTX_SIZE` | `4096` | 上下文窗口大小 |
|
||
| `YUANQI_LOG_LEVEL` | `info` | 日志级别 |
|
||
|
||
## 项目结构
|
||
|
||
```text
|
||
yuanqi/
|
||
├── pyproject.toml # 依赖:llama-cpp-python / FlagEmbedding / transformers
|
||
├── Dockerfile # 容器镜像
|
||
├── README.md # 本文件
|
||
├── src/
|
||
│ ├── main.py # FastAPI 入口(引擎初始化 + 路由注册)
|
||
│ ├── config.py # 配置加载(环境变量 → models/ 路径解析)
|
||
│ ├── endpoints/
|
||
│ │ ├── chat.py # LLM 对话端点(OpenAI 兼容)
|
||
│ │ ├── embeddings.py# 向量嵌入端点(OpenAI 兼容)
|
||
│ │ ├── rerank.py # 重排序端点(自定义 API)
|
||
│ │ └── health.py # 健康检查端点
|
||
│ ├── engine/
|
||
│ │ ├── base.py # 引擎抽象基类
|
||
│ │ ├── llm.py # llama-cpp-python LLM 引擎
|
||
│ │ ├── embedding.py # FlagEmbedding (BGE-M3) 引擎
|
||
│ │ └── reranker.py # transformers CrossEncoder 引擎
|
||
│ └── models/
|
||
│ └── schemas.py # Pydantic 请求/响应模型
|
||
└── tests/
|
||
└── ...
|
||
```
|
||
|
||
## Docker 部署
|
||
|
||
详见《docker/README.md》及 `docker-compose.app.yml` 中 `hunjing-yuanqi` 服务定义。
|
||
|
||
**注意:** 容器部署时需将宿主机 `models/` 目录挂载到容器内:
|
||
|
||
```yaml
|
||
hunjing-yuanqi:
|
||
volumes:
|
||
- ../models:/app/models # 挂载模型目录
|
||
- ../logs:/app/logs # 日志
|
||
```
|
||
|
||
## 设计文档
|
||
|
||
详细的架构设计与决策见 `docs/architecture/system-architecture.md`。
|