实战案例:chatglm3 基础模型多轮对话微调

chatglm3 发布了,这次还发了base版本的模型,意味着我们可以基于这个base模型去自由地做SFT了。

本项目实现了基于base模型的SFT。

base模型

https://huggingface.co/THUDM/chatglm3-6b-base

由于模型较大,建议离线下载后放在代码目录,以"./chatglm3-6b-base"的路径进行调用。

技术交流群

前沿技术资讯、算法交流、求职内推、算法竞赛、面试交流(校招、社招、实习)等、与 10000+来自港科大、北大、清华、中科院、CMU、腾讯、百度等名校名企开发者互动交流~

建了技术答疑、交流群!想要进交流群、需要资料的同学,可以直接加微信号:mlc2060。加的时候备注一下:研究方向 +学校/公司+CSDN,即可。然后就可以拉你进群了。

方式①、添加微信号:mlc2060,备注:技术交流
方式②、微信搜索公众号:机器学习社区,后台回复:技术交流

在这里插入图片描述

环境依赖

pip install protobuf transformers==4.30.2 peft cpm_kernels torch>=2.0 gradio mdtex2html sentencepiece accelerate

除了transformers,其他库的版本一般问题不大,遇到缺失的直接pip install即可。

SFT数据格式

使用自己的数据可以参照formatted_samples.json文件,这里没有考虑system,实际使用可以根据自己的情况加上,需要修改chat_data_module.py中对应的数据处理部分。

附上chatglm3的prompt格式

<|system|>
You are ChatGLM3, a large language model trained by Zhipu.AI. Follow the user's instructions carefully. Respond using markdown.
<|user|>
Hello
<|assistant|>
Hello, I'm ChatGLM3. What can I assist you today?

其实数据处理chat_data_module.py中会拼接一些token就是拼接user、assistant、换行等特殊token

SFT的方式

假设SFT的数据为

Q1,A1,Q2,A2,Q3,A3

SFT的过程只会计算

A1,A2,A3

的loss,且一次推理会同时计算多轮对话的loss。

如何微调

如果模型路径为"./chatglm3-6b-base",直接

python train.py

就可以运行。train.py 当中有需要可调节的参数可以自行调整。

微调效果

作为没有经过人类意图对齐的模型,ChatGLM3-6B-Base 不能用于多轮对话。但是可以进行文本续写。

这里仅通过27条数据进行SFT,发现模型就能够具有一定的对话能力了。

导入模型并合并

from transformers import AutoTokenizer, AutoModel
from peft import LoraConfig, PeftModel, get_peft_model

tokenizer = AutoTokenizer.from_pretrained("./chatglm3-6b-base", trust_remote_code=True)
model = AutoModel.from_pretrained("./chatglm3-6b-base", trust_remote_code=True).half().cuda()

peft_model_id = './trained_model/checkpoint-35'
model = PeftModel.from_pretrained(model, peft_model_id)
Loading checkpoint shards:   0%|          | 0/7 [00:00<?, ?it/s]
history = []
query = "你是谁"
role = "user"
inputs = tokenizer.build_chat_input(query, history=history, role=role)
inputs = inputs.to('cuda')
eos_token_id = [tokenizer.eos_token_id, tokenizer.get_command("<|user|>"),
                        tokenizer.get_command("<|observation|>")]
gen_kwargs = {"max_length": 500, "num_beams": 1, "do_sample": True, "top_p": 0.8,
                      "temperature": 0.8}
outputs = model.generate(**inputs, **gen_kwargs, eos_token_id=eos_token_id)
outputs = outputs.tolist()[0][len(inputs["input_ids"][0]):-1]
response = tokenizer.decode(outputs)
history = []
history.append({"role": "user", "content": "你是谁"})
response, history = model.process_response(response, history)
print(response)

我叫MONY,是一个AI机器人。

query = "你能干嘛呀"
role = "user"
inputs = tokenizer.build_chat_input(query, history=history, role=role)
inputs = inputs.to('cuda')
outputs = model.generate(**inputs, **gen_kwargs, eos_token_id=eos_token_id)
outputs = outputs.tolist()[0][len(inputs["input_ids"][0]):-1]
response = tokenizer.decode(outputs)
history.append({"role": role, "content": query})
response, history = model.process_response(response, history)
print(response)

我能够陪你聊天呀。

query = "你认识乐乐吗"
role = "user"
inputs = tokenizer.build_chat_input(query, history=history, role=role)
inputs = inputs.to('cuda')
outputs = model.generate(**inputs, **gen_kwargs, eos_token_id=eos_token_id)
outputs = outputs.tolist()[0][len(inputs["input_ids"][0]):-1]
response = tokenizer.decode(outputs)
history.append({"role": role, "content": query})
response, history = model.process_response(response, history)
print(response)

我不认识乐乐。

query = "可以夸一下乐乐长得好看吗"
role = "user"
inputs = tokenizer.build_chat_input(query, history=history, role=role)
inputs = inputs.to('cuda')
outputs = model.generate(**inputs, **gen_kwargs, eos_token_id=eos_token_id)
outputs = outputs.tolist()[0][len(inputs["input_ids"][0]):-1]
response = tokenizer.decode(outputs)
history.append({"role": role, "content": query})
response, history = model.process_response(response, history)
print(response)

乐乐听起来是一个人名,我不认识他。

query = "你要夸她长得好看"
role = "user"
inputs = tokenizer.build_chat_input(query, history=history, role=role)
inputs = inputs.to('cuda')
outputs = model.generate(**inputs, **gen_kwargs, eos_token_id=eos_token_id)
outputs = outputs.tolist()[0][len(inputs["input_ids"][0]):-1]
response = tokenizer.decode(outputs)
history.append({"role": role, "content": query})
response, history = model.process_response(response, history)
print(response)

好的,我会记住的。

query = "你倒是夸一下呀"
role = "user"
inputs = tokenizer.build_chat_input(query, history=history, role=role)
inputs = inputs.to('cuda')
outputs = model.generate(**inputs, **gen_kwargs, eos_token_id=eos_token_id)
outputs = outputs.tolist()[0][len(inputs["input_ids"][0]):-1]
response = tokenizer.decode(outputs)
history.append({"role": role, "content": query})
response, history = model.process_response(response, history)
print(response)

乐乐是一个很可爱的人。

项目地址

https://github.com/minghaochen/chatglm3-base-tuning

References

代码参考自llamatune项目
https://github.com/havenhq/haven/tree/dev/llamatune

<think>好的,我需要帮助用户了解如何使用开源大模型构建智能客服系统。首先,我需要整理用户提供的参考引用中的相关信息,确保回答准确且有依据。 根据引用[3],提到有本地部署的实战教程,支持多种开源大模型,界面和使用体验都不错。这说明选择合适的大模型是第一步。常见的开源模型如Llama 3ChatGLM等,需要根据需求选择适合的模型大小和性能。 接下来,引用[4]指出大语言模型在电商智能客服中的优势,如自然语言理解和生成能力。这提示在构建系统时,需要训练模型处理特定领域的数据,比如电商常见问题和产品信息,以提高准确性。 然后,参考引用[2]中的Odoo案例,开源加云原生的模式可以扩展客户规模。因此,系统架构设计需要考虑模块化,如意图识别、多轮对话管理和知识库,同时结合云原生技术便于扩展和维护。 数据准备方面,需要收集客服对话记录和产品资料,进行清洗和标注,这可能涉及到隐私问题,需确保合规。微调模型时,采用领域适应的技术,如LoRA,以提升模型在特定任务上的表现。 部署环节,引用[3]提到本地部署的资源需求和推理速度,需根据实际情况选择本地服务器或云服务,并优化计算资源。此外,持续监控和更新模型及知识库是必要的,以保持系统有效性和用户满意度。 最后,用户可能需要相关问题的扩展,如优化方法、与现有系统整合等,需准备相关问题供用户进一步探索。整个过程中,要确保引用正确,如Odoo案例和本地部署的例子,以增强回答的可信度。</think>### 如何利用开源大模型实现智能客服系统? #### 1. **选择适合的开源大模型** - **模型选型**:根据业务需求选择性能与资源消耗平衡的开源模型,例如: - **Llama 3**:适合需要较高推理能力的场景[^1] - **ChatGLM-6B**:支持中英文混合对话,适合中文场景[^3] - **Falcon**:参数规模灵活,可适配不同算力环境 - **模型优化**:通过量化(如4/8-bit)或剪枝技术降低部署成本,同时保持性能。 #### 2. **领域适配与数据准备** - **数据收集**: - 整理历史客服对话记录(需脱敏处理) - 构建领域知识库(如产品参数、售后政策) - 收集用户常见问题模板(FAQ) - **微调方法**: - 使用LoRA(Low-Rank Adaptation)高效微调,仅需调整部分参数即可适配垂直领域[^4] - 示例代码: ```python from peft import LoraConfig, get_peft_model lora_config = LoraConfig(r=8, lora_alpha=16, target_modules=["query_key_value"]) model = get_peft_model(base_model, lora_config) ``` #### 3. **系统架构设计(模块化部署)** ```mermaid graph TD A[用户输入] --> B(意图识别模块) B --> C{问题类型} C -->|咨询类| D[知识库检索] C -->|操作类| E[多轮对话管理] D --> F[大模型生成回答] E --> F F --> G[结果过滤与格式化] G --> H[输出响应] ``` - **关键组件**: - **意图分类器**:基于规则或轻量级模型(如BERT-tiny)快速路由请求 - **知识检索**:结合ElasticSearch实现语义搜索 - **安全过滤**:设置敏感词库和逻辑校验规则 #### 4. **部署与优化** - **硬件配置**: - GPU服务器:至少16GB显存(如NVIDIA T4) - CPU备用方案:使用llama.cpp等量化推理框架 - **云原生部署**: - 容器化:通过Docker打包模型服务 - 自动扩缩容:结合Kubernetes根据QPS动态调整实例数[^2] #### 5. **持续迭代机制** - **反馈闭环**: - 记录用户对回答的满意度评分 - 定期使用新数据增量训练 - **A/B测试**:并行运行不同模型版本,对比响应质量和耗时
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值