详细的 qwen:14b 小说专家微调操作手册 ,基于 LoRA 高效微调(适合消费级显卡):
一、环境准备
bash
# 1. 创建专用环境
conda create -n novel_qwen python=3.10 -y
conda activate novel_qwen
# 2. 安装核心依赖(推荐 LLaMA-Factory,最成熟)
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
pip install "llamafactory[torch,metrics]"
# 3. 验证安装
llamafactory-cli version
二、准备小说训练数据
数据格式(JSONL)
创建 novel_dataset.json,每条包含 instruction(写作要求)、input(题材/设定)、output(正文):
json
[
{
"instruction": "根据以下设定创作一段玄幻小说的开篇,要求氛围神秘,节奏紧凑",
"input": "题材:东方玄幻\n主角:山村少年,觉醒双生武魂\n场景:月夜下的古老祭坛",
"output": "血月高悬。\n\n青石村的少年跪在祖祠前的祭坛上,额头抵着冰凉的玄武岩。十七年了,他从未见过祖祠今夜这般模样------那些斑驳的图腾在月光下泛着血色的光,仿佛有活物在其中游走。\n\n\"林渊,时辰到了。\"长老的声音像是从地底传来。\n\n少年抬起头,看见自己投在地上的影子正在分裂。左侧的影子化作龙形,右侧的影子凝成剑意。双生武魂!千年未见的双生武魂!\n\n祭坛突然震动,地底传来锁链崩断的轰鸣......"
},
{
"instruction": "续写以下都市异能小说的对话场景,突出人物性格反差",
"input": "场景:咖啡厅\n人物A:表面是普通大学生,实则是S级异能者\"暗影\"\n人物B:异能管理局调查员,不知道A的真实身份\n情节:B正在调查近期异能者失踪案,无意中向A询问线索",
"output": "苏晚搅动着手中的拿铁,目光看似随意地扫过窗外。\n\n\"所以,同学,你最近有没有见过什么...特别的人?\"对面的调查员陈默递过一张照片,\"比如这个人,上周三在图书馆附近出现过。\"\n\n苏晚瞥了眼照片。那是他三天前处理掉的B级通缉犯。\n\n\"没见过。\"他露出乖巧的学生式微笑,手指却轻轻敲击着桌面------三下短,两下长。这是暗影组织内部的暗号:【猎物已清除,无需后续】。\n\n陈默皱眉:\"你敲桌子的习惯很特别。\"\n\n\"备考压力大。\"苏晚推了推眼镜,\"学长,我下午还有课,如果没有其他问题...\"\n\n他起身时,陈默的异能探测器突然发出刺耳的蜂鸣。S级警报!但只是一瞬间。\n\n\"设备故障了?\"陈默困惑地拍打着探测器。\n\n苏晚背对着他,嘴角微扬:\"可能是信号不好吧。学长,下次换个好点的设备。\""
}
]
数据规模建议:
- 短篇小说:500-2000 条样本
- 长篇小说:3000-10000 条样本(按章节切分)
三、配置文件(关键)
创建 novel_lora.yaml:
yaml
# 模型路径
model_name_or_path: qwen:14b # 或本地路径 ~/.ollama/models/qwen:14b
# 微调方法
finetuning_type: lora
lora_target: all # Qwen建议all,或指定 q_proj,v_proj,k_proj,o_proj,gate_proj,up_proj,down_proj
lora_rank: 16 # 小说生成建议16-64,越大拟合能力越强
lora_alpha: 32 # 通常 2*rank
lora_dropout: 0.05
# 数据配置
dataset_dir: .
dataset: novel_dataset # 对应 novel_dataset.json
template: qwen # Qwen官方模板
cutoff_len: 2048 # 小说长文本,可设4096需更多显存
max_samples: 10000
# 训练参数
output_dir: ./qwen_novel_expert
per_device_train_batch_size: 1 # 14B模型单卡通常只能跑batch=1
gradient_accumulation_steps: 8 # 累积8步模拟batch=8
num_train_epochs: 3 # 小说建议3-5轮
learning_rate: 5.0e-5 # LoRA可用较大学习率
warmup_ratio: 0.1
lr_scheduler_type: cosine
# 优化器
optim: adamw_torch
fp16: true # V100/RX系列用fp16,RTX30/40用bf16
# 日志保存
logging_steps: 10
save_steps: 100
plot_loss: true
# 特殊配置(小说生成关键)
neat_packing: true # 打包短样本提高效率
overwrite_cache: true
preprocessing_num_workers: 16
四、启动训练
bash
# 方式1:命令行启动
llamafactory-cli train novel_lora.yaml
# 方式2:Web UI(推荐可视化监控)
llamafactory-cli webui
# 然后在浏览器里导入 novel_lora.yaml 点击训练
显存需求参考:
- 14B + LoRA(r=16) + batch=1 + fp16:约 18-22GB 显存(RTX 4090 24GB 刚好)
- 如果爆显存:减小
cutoff_len到 1024,或减小lora_rank到 8
五、模型合并与导出
训练完成后,将 LoRA 权重合并到基础模型:
bash
llamafactory-cli export \
--model_name_or_path qwen:14b \
--adapter_name_or_path ./qwen_novel_expert \
--template qwen \
--finetuning_type lora \
--export_dir ./qwen_novel_merged \
--export_size 2 \
--export_device cpu \
--export_legacy_format false
六、导入 Ollama 使用
1. 创建 Modelfile
dockerfile
FROM ./qwen_novel_merged
TEMPLATE """{{ if .System }}<|im_start|>system
你是资深网络小说作家"墨言",擅长:
- 玄幻/都市/言情多题材创作
- 节奏把控:黄金三章、爽点埋设、悬念设置
- 人物塑造:立体人设、性格反差、成长弧线
- 场景描写:五感沉浸、氛围渲染、画面感强
写作原则:爽文不小白,虐文有逻辑,甜文不油腻。<|im_end|>
{{ end }}{{ if .Prompt }}<|im_start|>user
{{ .Prompt }}<|im_end|>
{{ end }}<|im_start|>assistant
"""
PARAMETER temperature 0.8
PARAMETER num_ctx 4096 # 小说需要长上下文
PARAMETER repeat_penalty 1.1 # 防止重复
PARAMETER top_p 0.9
PARAMETER top_k 50
SYSTEM """你是资深网络小说作家"墨言"...(同上)"""
2. 创建并运行
bash
# 创建模型
ollama create qwen-novel -f ./Modelfile
# 运行测试
ollama run qwen-novel
>>> 帮我写一个关于"程序员穿越到修仙世界,用代码写符咒"的开篇,3000字,要有反差萌和硬核技术细节
七、进阶优化技巧
1. 分层学习率(如果显存够)
在 novel_lora.yaml 中添加:
yaml
# 让输出层(lm_head)学习率更高,更容易学会小说风格
# 需在代码中自定义,或使用 transformers Trainer 的 layer-wise lr_decay
2. 增量训练策略
第一轮训练后,如果效果不够:
bash
# 基于上一轮继续训练(热启动)
llamafactory-cli train \
novel_lora.yaml \
--resume_from_checkpoint ./qwen_novel_expert/checkpoint-500
3. 数据增强技巧
- 风格迁移:用 ChatGPT/Claude 将你的小说数据改写成金庸/猫腻/天蚕土豆等不同风格,扩充多样性
- 指令多样化:同一情节用"写一段""续写""改写得更虐""增加环境描写"等不同指令包装
八、效果验证指标
运行测试集评估:
bash
llamafactory-cli eval \
--model_name_or_path qwen_novel_merged \
--eval_dataset novel_eval \
--template qwen
人工验证清单:
- 是否保持人物一致性(同一角色性格不突变)
- 场景切换是否自然(转场不生硬)
- 悬念设置是否合理(埋坑有解)
- 语言风格是否符合题材(古偶不现代,都市不文言)
- 每章是否有"钩子"(让人想点下一章)
九、常见问题解决
| 问题 | 原因 | 解决 |
|---|---|---|
| 输出重复 | 训练数据有重复段落 | 增加 repeat_penalty 参数,或清洗数据去重 |
| 风格不稳定 | 训练轮数太少或学习率太高 | 增至5轮,或降低 lr 到 2e-5 |
| 显存溢出 | cutoff_len 太长 | 减至 1024,或使用 gradient_checkpointing |
| 生成太慢 | 合并后的模型太大 | 使用量化版本(int4)导出 |
完整工作流总结:
- 准备 500-2000 条高质量小说样本(JSONL)
- LLaMA-Factory LoRA 微调(rank=16,3轮)
- 合并权重 → Ollama 部署
- 用 System Prompt 固化作家人设
这样你的 qwen:14b 就能变成"墨言"------一个懂网文套路、会控制节奏、能写长文的专用作家 AI。