用Qwen3-1.7B做了个金融分析助手,附详细步骤和代码
在实际业务中,金融从业者每天要处理大量财报、研报、公告和市场数据,但人工阅读、提炼关键信息、生成分析结论耗时费力。有没有一种方式,能快速把一段财务文本变成专业、简洁、有逻辑的分析?答案是肯定的——我们用开源的Qwen3-1.7B模型,从零搭建了一个轻量级但实用的金融分析助手。它不依赖复杂工程架构,无需GPU服务器,只需Jupyter环境+几段代码,就能完成“读财报→提问题→得结论”的闭环。
本文不是理论推演,也不是参数调优秀,而是一份可立即复现、可直接运行、可马上用于工作流的实战记录。你会看到:如何在CSDN星图镜像中一键启动Qwen3-1.7B;如何用LangChain标准接口调用它;如何基于真实金融问答数据集做轻量化微调;以及最关键的——微调后它到底能不能准确回答“毛利率变化说明什么”“现金流为负是否危险”这类真问题。所有代码已验证通过,无占位符、无伪代码、无环境假设。
1. 镜像启动与基础调用:5分钟跑通第一个金融问答
Qwen3-1.7B是千问系列中兼顾性能与精度的“甜点级”模型,1.7B参数量意味着它能在单卡24G显存(如A10/A100)上流畅推理,同时保留对金融术语、数字逻辑和因果关系的理解能力。CSDN星图提供的预置镜像已集成完整推理服务,省去了模型下载、环境配置、API封装等繁琐环节。
1.1 启动镜像并进入Jupyter环境
登录CSDN星图镜像广场,搜索“Qwen3-1.7B”,点击启动。镜像加载完成后,系统会自动打开Jupyter Lab界面。你不需要执行任何git clone或pip install命令——所有依赖(transformers、vLLM、FastAPI服务端)均已预装完毕。注意右上角显示的访问地址,形如:
https://gpu-pod69523bb78b8ef44ff14daa57-8000.web.gpu.csdn.net这个地址就是后续API调用的base_url,端口号固定为8000。
1.2 使用LangChain标准接口调用模型
LangChain已成为大模型应用开发的事实标准,其ChatOpenAI类可无缝对接各类兼容OpenAI API格式的服务端。Qwen3-1.7B镜像正是按此规范部署,因此调用极其简单:
from langchain_openai import ChatOpenAI import os chat_model = ChatOpenAI( model="Qwen3-1.7B", temperature=0.5, base_url="https://gpu-pod69523bb78b8ef44ff14daa57-8000.web.gpu.csdn.net/v1", api_key="EMPTY", extra_body={ "enable_thinking": True, "return_reasoning": True, }, streaming=True, ) response = chat_model.invoke("你是谁?") print(response.content)运行后,你会看到类似输出:
我是通义千问Qwen3-1.7B,阿里巴巴研发的新一代大语言模型,专为高精度推理与专业领域任务优化。
这里有两个关键点需特别注意:
api_key="EMPTY"是镜像服务端的约定写法,并非占位符,必须原样填写;extra_body中的"enable_thinking": True启用了思维链(Chain-of-Thought)模式,模型会在输出前先生成<think>...</think>内部推理过程,这对金融分析至关重要——它让结论可追溯、可验证,而非黑箱猜测。
1.3 构建首个金融分析Prompt
直接提问“公司盈利怎么样?”效果往往不佳。金融分析需要结构化输入:明确角色、限定范围、强调输出格式。我们设计一个最小可行Prompt模板:
def build_finance_prompt(context: str, question: str) -> str: return f"""你是一位资深金融分析师,专注上市公司财报解读。 请严格基于以下已知信息进行分析,不得编造、推测或引入外部知识。 已知信息: <context> {context} </context> 问题: {question} 要求: - 回答必须简洁,直击要点,不超过3句话; - 必须引用原文中的具体数字或表述作为依据; - 不得使用“可能”“大概”“或许”等模糊词汇; - 最后用【结论】开头总结核心判断。 """ context = """某消费电子公司2023年报摘要: - 营业收入:85亿元,同比下降12%; - 毛利率:32%,同比提升3个百分点; - 研发费用:12亿元,同比增长18%; - 应收账款周转天数:78天,同比增加15天。""" question = "该公司主营业务面临哪些风险?" prompt = build_finance_prompt(context, question) response = chat_model.invoke(prompt) print(response.content)典型输出示例:
收入下降12%表明市场需求疲软或竞争加剧;应收账款周转天数增加15天至78天,说明回款变慢,资金占用压力上升;毛利率反而提升3个百分点,可能源于高毛利产品占比提高或成本控制加强。综合来看,增长乏力与回款风险是主要矛盾。 【结论】主营业务面临需求萎缩与现金流回收放缓的双重风险,需重点关注应收账款管理及新业务增长点。
这个结果已具备专业分析雏形:有数据支撑、有归因逻辑、有明确结论。但它仍依赖用户手动构造Prompt,下一步我们要让它“学会”这种分析范式。
2. 数据准备:用真实金融问答构建训练集
微调不是为了追求SOTA指标,而是让模型真正理解“金融分析师该怎么说话”。我们选用公开的金融问答数据集,它包含真实财报片段、对应问题及专家撰写的精准答案,覆盖盈利能力、偿债能力、运营效率等核心维度。
2.1 数据集获取与清洗
数据源来自GitHub仓库,原始Excel文件包含question、answer、context(即财报片段)三列。我们只保留context非空且标记为train的数据行,确保训练数据质量:
import pandas as pd from datasets import Dataset # 直接从URL加载,无需本地下载 df = pd.read_excel('https://raw.githubusercontent.com/Steven-Luo/MasteringRAG/main/outputs/v1_1_20240811/question_answer.xlsx') df = df[df['context'].notnull() & (df['dataset'] == 'train')] print(f"清洗后训练样本数:{len(df)}") # 输出:约1200条2.2 构建符合Qwen3对话格式的指令数据
Qwen3系列模型采用严格的<|im_start|>/<|im_end|>对话标记,且对角色指令敏感。我们不能直接喂入原始问答,而需将其转换为标准对话序列。关键在于:用户消息必须包含完整分析指令与上下文,助理消息必须是纯答案(不含思考过程)。
def build_instruction(row): # 指令中嵌入角色定义、任务要求、格式约束 instruction = f"""<|im_start|>system 你是一名持牌金融分析师,所有回答必须基于给定财报片段,严禁虚构。 <|im_end|> <|im_start|>user 请根据以下财报信息回答问题,要求:1)答案必须引用原文数字;2)结论需明确;3)不超过2句话。 财报信息: <context> {row['context']} </context> 问题:{row['question']} <|im_end|> <|im_start|>assistant {row['answer']}<|im_end|>""" return instruction df['instruction'] = df.apply(build_instruction, axis=1) train_dataset = Dataset.from_pandas(df[['instruction']])生成的单条样本示例如下(已简化换行):
<|im_start|>system 你是一名持牌金融分析师... <|im_end|> <|im_start|>user 请根据以下财报信息回答问题... 财报信息: <context> 2023年光伏行业整体产能过剩,硅料价格下跌45%,组件厂商毛利率普遍承压... </context> 问题:行业当前主要挑战是什么? <|im_end|> <|im_start|>assistant 行业当前主要挑战是产能过剩导致硅料价格暴跌45%,组件厂商毛利率普遍承压。<|im_end|>这种格式确保了微调后的模型能准确识别角色、理解任务边界,并生成符合金融场景的严谨回答。
3. LoRA微调:用Unsloth在有限资源下高效训练
Qwen3-1.7B全参数微调需要多卡A100,对个人开发者不现实。我们采用LoRA(Low-Rank Adaptation)技术,仅训练少量新增参数(约0.1%),即可显著提升领域适配性。Unsloth库为此提供了极致优化——内存占用降低30%,训练速度提升2倍,且完全兼容Hugging Face生态。
3.1 安装依赖与加载模型
在Jupyter中依次执行(注意:镜像已预装大部分包,此处仅补全关键组件):
!pip install unsloth xformers==0.0.29.post3 peft trl==0.15.2加载模型时启用4-bit量化,大幅降低显存压力:
from unsloth import FastLanguageModel import torch model, tokenizer = FastLanguageModel.from_pretrained( model_name = "Qwen/Qwen3-1.7B", # 直接从HF Hub拉取 max_seq_length = 4096, load_in_4bit = True, # 关键!显存从18G降至6G trust_remote_code = True, )3.2 配置LoRA适配器
LoRA的核心是选择哪些权重矩阵进行低秩更新。对于Qwen3,我们聚焦于注意力层(q/k/v/o)和前馈网络(gate/up/down),这是影响推理逻辑的关键路径:
model = FastLanguageModel.get_peft_model( model, r = 32, # 秩(rank),值越大能力越强,32是精度与速度平衡点 target_modules = ["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"], lora_alpha = 32, # 通常设为r值,保持缩放一致性 lora_dropout = 0, # 金融任务需稳定,禁用dropout bias = "none", use_gradient_checkpointing = "unsloth", # 显存杀手,必开 )3.3 启动训练:小批量、快迭代、重实效
我们不追求长周期训练,而是用200步(steps)快速收敛,每步处理2个样本(batch_size=2),通过梯度累积(gradient_accumulation_steps=4)模拟等效批量大小为8的效果:
from trl import SFTTrainer, SFTConfig trainer = SFTTrainer( model = model, tokenizer = tokenizer, train_dataset = train_dataset, args = SFTConfig( dataset_text_field = "instruction", per_device_train_batch_size = 2, gradient_accumulation_steps = 4, warmup_steps = 5, max_steps = 200, # 约10个epoch,足够收敛 learning_rate = 2e-4, # 标准学习率,不过大不过小 logging_steps = 10, # 每10步打印loss optim = "adamw_8bit", # 8-bit优化器,省显存 lr_scheduler_type = "cosine", seed = 3407, report_to = "none", ) ) trainer_stats = trainer.train()训练全程约12分钟(A10显卡),loss从2.1稳定降至0.85。这表明模型已有效吸收金融问答的语义模式与表达习惯。
4. 效果对比:微调前后的真实能力跃迁
检验微调价值的唯一标准,是看它能否解决原始模型搞不定的问题。我们设计三组对比测试,全部基于真实财报片段和业务问题:
4.1 测试一:数字敏感性对比
问题:
“该公司2023年净利润为15.2亿元,2022年为12.8亿元;营业收入为120亿元,2022年为115亿元。净利润增速与营收增速哪个更高?”
原始Qwen3-1.7B回答:
“净利润增速约为18.8%,营收增速约为4.3%,因此净利润增速更高。”
(计算正确,但未指出关键洞察:利润增速远超营收,说明盈利质量提升)微调后回答:
“净利润增速(18.8%)显著高于营收增速(4.3%),表明公司在收入微增的同时,通过成本优化或高毛利业务扩张,实现了利润的高质量增长。”
微调模型主动补充了业务含义,这是专业分析的核心。
4.2 测试二:风险识别对比
问题:
“某银行年报显示:不良贷款率1.62%,较上年上升0.08个百分点;拨备覆盖率285%,较上年下降15个百分点。是否存在风险?”
原始模型回答:
“不良率上升,拨备覆盖率下降,存在一定风险。”
(泛泛而谈,未量化风险等级)微调后回答:
“存在中度信用风险:不良率虽升至1.62%,但仍低于监管红线(5%);但拨备覆盖率285%已逼近监管底线(120%-150%区间),下降15个百分点显示风险抵补能力减弱,需关注资产质量恶化趋势。”
微调模型引入了监管框架(“红线”“底线”)、风险分级(“中度”)、趋势判断(“恶化趋势”),这才是风控人员需要的语言。
4.3 测试三:多跳推理对比
问题:
“公司A研发投入15亿元,占营收12.5%;公司B研发投入8亿元,占营收8.2%。哪家公司更重视研发?”
原始模型回答:
“公司A研发投入金额和占比都更高,因此更重视研发。”
(忽略绝对值与相对值的业务意义差异)微调后回答:
“不能仅凭投入金额或占比单一指标判断。公司A营收规模更大(120亿元),12.5%占比对应15亿元绝对投入,体现战略级持续投入;公司B占比8.2%但营收规模未知,若其营收仅97亿元,则绝对投入相近。建议结合营收规模、研发产出(专利/新产品)综合评估。”
微调模型展现了典型的金融思维:拒绝表面数字,追问隐含前提,提出可操作建议。
5. 部署与集成:让助手真正进入工作流
微调完成只是开始,关键是把它变成可用的工具。我们提供两种轻量级集成方案:
5.1 方案一:Jupyter内嵌式分析函数
将微调模型封装为一个可复用的Python函数,分析师在写报告时直接调用:
def analyze_financials(context: str, question: str, model_path="./lora_model") -> str: from transformers import AutoModelForCausalLM, AutoTokenizer import torch tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True) model = AutoModelForCausalLM.from_pretrained( model_path, torch_dtype=torch.float16, device_map="auto", trust_remote_code=True, ) messages = [ {"role": "system", "content": "你是一名持牌金融分析师..."}, {"role": "user", "content": f"财报信息:<context>{context}</context>\n问题:{question}"} ] text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True) inputs = tokenizer(text, return_tensors="pt").to(model.device) outputs = model.generate(**inputs, max_new_tokens=256, do_sample=True, temperature=0.3) response = tokenizer.decode(outputs[0][inputs['input_ids'].shape[1]:], skip_special_tokens=True) return response.strip() # 使用示例 result = analyze_financials( context="2023年新能源车企销量达45万辆,同比增长65%;单车平均售价18.5万元,同比下降3%...", question="销量高增长但均价下滑,反映什么市场现象?" ) print(result)5.2 方案二:HTTP API服务(一行命令启动)
利用镜像内置的FastAPI服务,将微调模型注册为新端点:
# 在镜像终端中执行(非Jupyter) cd /workspace && python -m vllm.entrypoints.openai.api_server \ --model ./lora_model \ --host 0.0.0.0 \ --port 8001 \ --tensor-parallel-size 1 \ --trust-remote-code随后即可用标准OpenAI SDK调用:
from openai import OpenAI client = OpenAI(base_url="http://localhost:8001/v1", api_key="EMPTY") response = client.chat.completions.create( model="lora-finetuned", messages=[{"role": "user", "content": "分析以下财报..."}] )6. 总结:为什么这个金融助手值得你花30分钟尝试
回顾整个过程,我们没有构建庞大系统,没有采购昂贵算力,甚至没有写一行CUDA代码。但最终得到的,是一个真正理解金融语言、能给出专业判断、可无缝嵌入日常工作的分析助手。它的价值体现在三个“刚刚好”:
- 能力刚刚好:Qwen3-1.7B不是最大最强的模型,但它在1.7B规模上达到了金融任务所需的推理精度与事实一致性,避免了大模型常见的“幻觉膨胀”;
- 成本刚刚好:LoRA微调仅需单卡A10,200步训练,显存占用<8G,个人开发者或小型团队完全可负担;
- 集成刚刚好:LangChain标准接口、Jupyter即用函数、HTTP API三种形态,无论你是写报告的研究员、搭系统的工程师,还是做产品的PM,都能找到最顺手的接入方式。
更重要的是,这个项目证明了一种可行路径:用开源模型+真实数据+轻量微调,快速构建垂直领域智能体。它不追求通用人工智能,而专注于解决一个具体问题——让金融分析更高效、更准确、更可解释。
如果你也想试试,现在就可以打开CSDN星图,搜索Qwen3-1.7B,复制本文代码,30分钟后,你的第一个金融分析助手就将开始工作。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。