基于 DeepSeek-R1 蒸馏的金融领域推理增强问答系统
RAG + QLoRA + 结构化推理链解析 —— 单张 RTX 4060 (8GB) 可完成训练与部署
🚀 快速开始 • 🏗️ 架构 • 📡 API • 🐳 部署 • 📊 评测
Finance-DeepSeek 是一款面向金融领域的生产级问答系统,基于 DeepSeek-R1-Distill-Qwen-1.5B 构建。该模型由 DeepSeek-R1 671B 满血版经知识蒸馏得到,原生具备多步数值推理与自我验证能力。
系统通过三大核心模块实现金融场景下的高精度问答:
- QLoRA 领域对齐微调 —— 4-bit NF4 量化 + LoRA rank 128,在单卡 RTX 4060 上完成金融领域适配
- FAISS 稠密检索增强 (RAG) ——
finance-embeddings-investopedia专业金融 Embedding + Top-8 上下文注入,抑制幻觉 - 结构化推理链解析 —— 自动提取
<think>推理过程与<answer>最终答案,支持 SSE 流式"边想边答"
💡 核心设计哲学:不再"教模型推理",而是"规范模型已有的推理能力并注入金融领域知识"。
- 基座模型:
DeepSeek-R1-Distill-Qwen-1.5B(Qwen2.5-Math-1.5B 架构,经 671B 蒸馏) - 量化方案:4-bit NF4 + double quant + bf16 混合精度计算
- 基座仅占约 1GB 显存,为训练与推理留出充裕空间
- 训练峰值 ≤ 6.5GB,推理峰值 ≤ 4GB,完美适配消费级显卡
- Embedding:
FinLang/finance-embeddings-investopedia(金融领域专用,dim=768) - 备选回退:
yiyanghkust/finbert-tone(FinBERT 金融情感模型) - 索引引擎:FAISS 自动选择
IndexFlatIP(<5万条)或IndexHNSWFlat(≥5万条) - 增量更新:支持
add()实时添加新文档,无需全量重建 - Prompt 严格约束:"若材料不足以回答,请明确说明'根据现有资料无法确定'"
- 模型输出自带
<think>...</think>结构化推理链 - 系统自动解析为
reasoning_steps: List[str] - SSE 流式输出:先传输思考过程,再传输最终答案
- 前端可实现"打字机效果"展示模型思维过程
- 支持调用 DeepSeek-R1 API(
deepseek-reasoner)生成高质量推理链 - 自动回退到本地 DeepSeek-R1-Distill-Qwen-7B
- 训练数据内置数值一致性校验(1% 容差),过滤推理链与答案矛盾的样本
| 模式 | 说明 | 适用场景 |
|---|---|---|
closed-book |
纯模型自身知识 | 通用金融概念解释 |
rag |
RAG 检索增强 | 需要引用外部资料的 factual 问答 |
rag+reasoning |
RAG + 结构化推理链解析 | 数值计算、比率分析、需要可解释性的场景 |
- 使用
mDeBERTa-v3-base-xnli-multilingual-nli-2mil7判断生成内容与上下文的蕴含关系 - 替代粗糙的"数字重叠"启发式,评测结果更具可信度
- 同时支持 Recall@K、MRR、EM、Numeric EM、BLEU-4、ROUGE-L、Chain Completeness
- ✅ 输入敏感词过滤(色情、赌博、洗钱、内幕交易等)
- ✅ temperature 硬封顶 0.7,防止金融场景幻觉
- ✅ Token 级精确截断(
max_input_length=1024) - ✅ 单并发 semaphore 保护,适配 RTX 4060 单卡
┌─────────────────────────────────────────────────────────────────┐
│ 用户请求层 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ Closed-Book │ │ RAG │ │ RAG + Reasoning │ │
│ └──────┬───────┘ └──────┬───────┘ └──────────┬───────────┘ │
└──────────┼────────────────┼─────────────────────┼──────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────┐
│ FastAPI 服务层 │
│ /v1/chat/completions │ /v1/ingest │ /v1/health │
│ • OpenAI-compatible │ • 增量索引 │ • GPU/模型/索引状态 │
│ • SSE 流式输出 │ • 安全过滤 │ │
└─────────────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────┐
│ 推理引擎 (InferenceEngine) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ Prompt 拼接 │ │ model.gen │ │ ChainParser + Validator│ │
│ │ • Top-8 检索 │ │ • 4-bit QL │ │ • <think> 提取 │ │
│ │ • 模板注入 │ │ • bf16 计算 │ │ • 数值一致性校验 │ │
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 数据与模型层 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ DeepSeek-R1 │ │ LoRA Adapter│ │ FAISS Index │ │
│ │ Distill-1.5B │ │ (QLoRA r=128)│ │ • finance-embedding │ │
│ │ 4-bit 量化 │ │ 金融领域对齐 │ │ • 768 dim │ │
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
由于 GitHub 单文件 100MB 限制及环境独立性原则,以下文件未包含在仓库中,但你只需运行对应脚本即可自动生成或下载:
| 缺失文件/目录 | 原因 | 大小 | 获取方式 |
|---|---|---|---|
models/base/**/*.safetensors |
基座模型权重过大 | ~3.5 GB | 首次运行时自动从 HuggingFace 下载(deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B) |
models/adapters/**/adapter_model.safetensors |
LoRA 适配器权重 | ~590 MB | 方式①:运行 python run_training.py 自行训练 方式②:从 HuggingFace 下载预训练 adapter(如有发布) |
data/corpus/faiss_index.index |
FAISS 向量索引 | ~15 KB(随语料增长) | 运行 python run_data_gen.py 自动重建 |
data/corpus/chunk_metadata.json |
Chunk 元数据 | ~1 KB | 同上,随索引一起生成 |
data/finetune/*.jsonl |
SFT 训练数据 | ~500 KB | 同上,run_data_gen.py 自动生成 Alpaca + FinQA 数据 |
venv/ |
Python 虚拟环境 | ~5 GB | 自行创建:python -m venv venv |
evaluation/results/ |
评测输出图表 | 运行时生成 | 运行 python run_benchmark.py 自动生成 |
# 1. 创建虚拟环境
python -m venv venv
# Linux/macOS: source venv/bin/activate
# Windows: venv\Scripts\activate
# 2. 安装依赖
pip install -r requirements.txt
# 3. 一键生成数据 + 索引(自动下载 Embedding 模型和 tokenizer)
python run_data_gen.py
# 4. (可选)训练 LoRA Adapter
python run_training.py完成以上步骤后,所有缺失文件均已就位,可直接启动 API 服务。
| 项目 | 要求 |
|---|---|
| GPU | NVIDIA RTX 4060 8GB 或同等级(支持 CUDA 12.x) |
| 显存峰值(训练) | ≤ 6.5 GB |
| 显存峰值(推理) | ≤ 4 GB |
| 系统内存 | ≥ 16 GB 推荐 |
| 磁盘空间 | ≥ 20 GB(含模型、索引与依赖) |
git clone https://github.com/ShaneLiu04/Finance-DeepSeek.git
cd Finance-DeepSeek/finance_deepseek
python -m venv venv
# Linux/macOS
source venv/bin/activate
# Windows
venv\Scripts\activate
pip install -r requirements.txt# 生成 SFT 训练数据 + 构建 FAISS 索引
python run_data_gen.py首次运行会自动:
- 下载
FinLang/finance-embeddings-investopedia(约 500MB)- 生成 500 条 Alpaca 基础数据 + 3 条 FinQA Demo 数据
- 构建 5 条演示语料的 FAISS 索引
(可选)接入教师模型蒸馏:
export DEEPSEEK_API_KEY="sk-your-api-key-here" # Linux/macOS
set DEEPSEEK_API_KEY=sk-your-api-key-here # Windows
python run_data_gen.py# Linux/macOS
PYTHONPATH="..:." python run_api.py
# Windows
set PYTHONPATH=..;.
python run_api.py服务将在 http://localhost:8000 启动。
curl http://localhost:8000/v1/health期望返回:
{
"status": "ok",
"model_loaded": true,
"adapter_loaded": true,
"index_loaded": true,
"gpu_memory_used_gb": 2.5,
"gpu_memory_total_gb": 8.0,
"index_doc_count": 5
}| 端点 | 方法 | 说明 |
|---|---|---|
/ |
GET | 系统信息与端点列表 |
/v1/health |
GET | 健康检查(GPU 内存、模型/adapter/索引状态) |
/v1/chat/completions |
POST | OpenAI-compatible 对话接口 |
/v1/ingest |
POST | 实时文档摄入(分块、Embedding、增量索引) |
/docs |
GET | FastAPI 自动 Swagger UI |
Request Body:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
messages |
List[ChatMessage] |
✅ | 对话历史,[{role:"user", content:"..."}] |
mode |
string |
❌ | "closed-book" / "rag" / "rag+reasoning"(默认 rag+reasoning) |
stream |
bool |
❌ | 是否 SSE 流式返回(默认 false) |
temperature |
float |
❌ | 采样温度,范围 [0.0, 0.7](默认 0.6) |
top_p |
float |
❌ | nucleus sampling(默认 0.9) |
max_tokens |
int |
❌ | 最大生成 token 数 [1, 2048](默认 1024) |
cURL 示例:
curl -X POST http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"messages": [{"role": "user", "content": "某公司股票价格 80 元,EPS 为 4 元,市盈率是多少?"}],
"mode": "rag+reasoning",
"stream": false,
"temperature": 0.6
}'Response 示例(rag+reasoning 模式):
{
"id": "chatcmpl-a1b2c3d4",
"object": "chat.completion",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "<think>\n步骤1: 识别已知条件:股价 = 80 元,EPS = 4 元。\n步骤2: 应用市盈率公式:P/E = 80 / 4 = 20。\n步骤3: 验证:20 倍属于合理估值区间。\n</think>\n<answer>\n20\n</answer>"
},
"finish_reason": "stop"
}
]
}import requests
resp = requests.post(
"http://localhost:8000/v1/chat/completions",
json={
"messages": [{"role": "user", "content": "投资 10000 元,年利率 5%,3 年复利本利和?"}],
"mode": "rag+reasoning",
"stream": True,
"temperature": 0.6,
},
stream=True,
)
for line in resp.iter_lines():
if line:
print(line.decode("utf-8"))输出格式:
data: 步骤1: 识别参数...
data: 步骤2: 代入公式...
...
event: parsed
data: {"reasoning_steps": [...], "final_answer": "11576.25", ...}
data: [DONE]
curl -X POST http://localhost:8000/v1/ingest \
-H "Content-Type: application/json" \
-d '{
"documents": [
{
"text": "央行降准 0.5 个百分点,释放长期资金约 1 万亿元...",
"source_url": "https://example.com/news/1",
"category": "货币政策",
"title": "央行降准"
}
]
}'返回:
{"status": "success", "chunks_indexed": 2, "total_indexed": 7}cd finance_deepseek
python run_api.pydocker-compose up --builddocker-compose.yml 已配置:
- NVIDIA CUDA 12.1 Runtime 基础镜像
- GPU 资源预留
- 健康检查自动重启
- 端口映射
8000:8000
# 1. 准备数据
python run_data_gen.py
# 2. 启动训练
python run_training.py训练产物:
models/adapters/finance_qlora/final_adapter/adapter_model.safetensorsmodels/adapters/finance_qlora/final_adapter/adapter_config.json
训练配置(
config.yaml):
- LoRA: r=128, alpha=32, target_modules=[q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj]
- Batch: per_device=2, gradient_accumulation=2(有效 batch=4)
- Epochs: 3, LR: 1e-4, Scheduler: cosine, Optimizer: paged_adamw_8bit
一键执行消融实验:
python run_benchmark.py输出:
- 终端 Markdown 表格
evaluation/results/ablation_comparison.png(柱状图可视化)evaluation/results/ablation_results.json
| 指标 | 目标值 | 说明 |
|---|---|---|
| Faithfulness@8 | ≥ 72% | 事实性问答严格保真度(NLI 模型判定) |
| Exact Match (EM) | ≥ 15% | 字符串完全匹配率 |
| Numeric EM | ≥ 65% | 数值答案相对误差 1% 内匹配率 |
| 推理延迟 | < 3s | 非流式单请求,RTX 4060 |
| 训练显存峰值 | ≤ 6.5GB | 单卡 RTX 4060 安全余量 |
| 推理显存峰值 | ≤ 4GB | 单卡 RTX 4060 安全余量 |
Finance-DeepSeek/
├── finance_deepseek/
│ ├── api/
│ │ ├── main.py # FastAPI 服务入口(lifespan、端点、安全过滤)
│ │ ├── schemas.py # Pydantic 模型(OpenAI-compatible)
│ │ ├── inference.py # 推理引擎(3 模式路由、SSE 流式、Token 截断)
│ │ └── dependencies.py # 全局单例(AppState)
│ ├── rag/
│ │ ├── indexer.py # FAISS 索引构建 + 增量 add()
│ │ ├── retriever.py # DenseRetriever(Top-K + 可选重排)
│ │ └── embeddings.py # EmbeddingProvider(金融模型 + 自动回退)
│ ├── reasoning/
│ │ ├── chain_parser.py # <think>/<answer> 解析引擎
│ │ ├── validator.py # 推理链-答案数值一致性校验
│ │ └── test_chain_parser.py # 单元测试
│ ├── training/
│ │ ├── qlora_trainer.py # QLoRA SFT 训练入口
│ │ └── data_generator.py # 教师模型蒸馏数据生成(DeepSeek-R1 API)
│ ├── evaluation/
│ │ ├── metrics.py # EM / Numeric EM / Faithfulness@K / BLEU / ROUGE
│ │ └── benchmark.py # 消融实验 + matplotlib 可视化
│ ├── data/
│ │ ├── corpus/ # 语料分块 + FAISS 索引 + chunk_metadata
│ │ └── finetune/ # SFT 训练数据(Alpaca + FinQA)
│ ├── models/
│ │ ├── base/ # DeepSeek-R1-Distill-Qwen-1.5B(自动下载)
│ │ └── adapters/ # LoRA Adapter 输出
│ ├── config.yaml # 全局 YAML 配置
│ ├── requirements.txt # Python 依赖
│ ├── run_api.py # 一键启动 API
│ ├── run_training.py # 一键启动训练
│ ├── run_data_gen.py # 一键生成数据 + 索引
│ ├── run_benchmark.py # 一键评测
│ ├── test_deploy.py # 部署验证脚本
│ ├── Dockerfile # CUDA 12.1 Runtime 镜像
│ └── docker-compose.yml # Docker Compose 编排
└── README.md # 本文档
| 层级 | 技术选型 |
|---|---|
| 基座模型 | deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B |
| 微调框架 | transformers + peft + trl + bitsandbytes (QLoRA) |
| 训练精度 | 4-bit NF4 + bfloat16 |
| 向量检索 | faiss-gpu + sentence-transformers |
| Embedding | FinLang/finance-embeddings-investopedia(主选)/ finbert-tone(备选) |
| NLI 评测 | MoritzLaurer/mDeBERTa-v3-base-xnli-multilingual-nli-2mil7 |
| API 服务 | FastAPI + Uvicorn + SSE 流式输出 |
| 配置管理 | YAML 驱动 |
| 容器化 | Docker + docker-compose |
- QLoRA 领域微调框架
- FAISS 稠密检索 + 增量更新
- 结构化推理链解析 + SSE 流式
- 教师模型蒸馏流水线(DeepSeek-R1 API)
- NLI 级 Faithfulness 评测
- 生产安全过滤 + Token 截断
- 接入真实 SEC 10-K / 央行政策语料库
- cross-encoder 二阶段精排(rerank)
- 多轮对话记忆与上下文压缩
- vLLM / TGI 推理加速
- Gradio / Streamlit 前端演示界面
欢迎提交 Issue 和 PR!
- Fork 本仓库
- 创建功能分支:
git checkout -b feature/amazing-feature - 提交更改:
git commit -m 'Add amazing feature' - 推送分支:
git push origin feature/amazing-feature - 提交 Pull Request
请确保代码遵循 PEP8,关键函数包含 Docstring,并补充相应单元测试。
本项目采用 MIT License 开源协议。
- DeepSeek-AI / DeepSeek-R1-Distill-Qwen — 强大的推理蒸馏基座
- Qwen2.5-Math — 优秀的数学推理能力
- Hugging Face PEFT / TRL — 高效微调生态
- FAISS — 高性能向量检索
- FinLang / finance-embeddings-investopedia — 金融领域专用 Embedding
如果本项目对您有帮助,请点亮 ⭐ Star,让更多人发现它!