大语言模型代码实现对话交互全流程解析

在大语言模型(LLM)的应用中,看似简单的“提问-回答”背后,隐藏着一套严谨的技术流程。无论是ChatGPT、Qwen还是LLaMA等模型,其对话交互的核心逻辑都可以归纳为六个关键步骤。本文将以代码实例为基础,详细拆解每个步骤的作用,并通过对比解析,帮助你理解“模型为什么能听懂人话”。

核心流程概览

大语言模型的对话交互本质是“人类语言→模型可理解的输入→模型生成→人类可理解的输出”的闭环,具体可分为以下六个步骤:

  1. 分词器确定(Tokenizer Selection)
  2. 模型确定(Model Selection)
  3. 构建对话(Construct Conversation)
  4. 模板化对话(Template the Conversation)
  5. 回复生成(Generate Response)
  6. 解码(Decode the Output)

接下来,我们以Qwen2.5-3B-Instruct模型为例,通过代码实操展示每个步骤的细节。

代码实操:完整流程示例

我们将实现一个简单的对话功能:向模型提问“什么是大语言模型?”,并获取结构化回复。

环境准备

首先确保安装必要的库:

pip install modelscope transformers torch datasets peft trl

完整代码

# 步骤1:分词器确定(Tokenizer Selection)
from modelscope import AutoTokenizer, AutoModelForCausalLM
import torch

# 选择与模型匹配的分词器(Qwen2.5专用)
tokenizer = AutoTokenizer.from_pretrained(
    "Qwen/Qwen2.5-3B-Instruct",
    trust_remote_code=True
)
# 设置padding token(与结束token一致,Qwen模型的常见配置)
tokenizer.pad_token = tokenizer.eos_token


# 步骤2:模型确定(Model Selection)
# 加载Qwen2.5-3B对话模型(对话模型已训练好理解对话格式)
model = AutoModelForCausalLM.from_pretrained(
    "Qwen/Qwen2.5-3B-Instruct",
    torch_dtype=torch.bfloat16,  # 混合精度加速
    device_map="auto",  # 自动分配设备(优先GPU)
    trust_remote_code=True
)


# 步骤3:构建对话(Construct Conversation)
# 用列表结构存储对话历史,包含角色(role)和内容(content)
messages = [
    {"role": "system", "content": "你是一个简洁的AI助手,用中文回答问题。"},
    {"role": "user", "content": "什么是大语言模型?"}
]


# 步骤4:模板化对话(Template the Conversation)
# 将对话转换为模型训练时"认识"的格式
formatted_text = tokenizer.apply_chat_template(
    messages,
    tokenize=False,  # 返回文本格式(非token ID)
    add_generation_prompt=True  # 关键:添加"助手开始生成"的标记
)


# 步骤5:回复生成(Generate Response)
# 将文本转换为模型可接受的输入张量
model_inputs = tokenizer(
    [formatted_text],  # 传入列表以保持batch维度
    return_tensors="pt"  # 返回PyTorch张量
).to(model.device)  # 移至模型所在设备(GPU/CPU)

# 模型生成回复(控制生成参数)
generated_ids = model.generate(
    **model_inputs,
    max_new_tokens=200,  # 限制最大生成长度
    temperature=0.7,  # 控制随机性(0=确定,1=多样)
    pad_token_id=tokenizer.pad_token_id
)


# 步骤6:解码(Decode the Output)
# 将生成的token ID转换为人类可读文本
response = tokenizer.batch_decode(
    generated_ids,
    skip_special_tokens=True  # 去掉<|endoftext|>等特殊标记
)[0]  # 取batch中的第一个结果

print("模型回复:\n", response)

步骤拆解与对照解析

1. 分词器确定(Tokenizer Selection)

作用:将人类语言拆分为模型可理解的“最小单位”(token)。
代码关键

tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-3B-Instruct")
  • 每个模型都有专属分词器(如Qwen的分词器无法用于LLaMA),因为它们的“词汇表”不同。
  • 分词器会将文本转换为数字ID(如“大语言模型”可能被拆分为[3210, 1567, 4521])。

对照实验
如果用错分词器(如用GPT-2的分词器处理Qwen模型),会导致token ID与模型词汇表不匹配,输出会变成乱码。

2. 模型确定(Model Selection)

作用:加载预训练模型作为“大脑”,负责理解输入并生成回复。
代码关键

model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-3B-Instruct")
  • 对话模型(如带-Instruct后缀的模型)已通过训练学会理解对话格式,而基础模型(如GPT-2)则需要手动设计格式。

对照实验
用基础模型(如GPT-2)直接处理对话会出现逻辑混乱(可能重复用户问题),而对话模型能自然区分“提问”和“回答”。

3. 构建对话(Construct Conversation)

作用:用结构化数据整理对话历史,明确角色和内容。
代码关键

messages = [
    {"role": "system", "content": "你是一个简洁的AI助手"},
    {"role": "user", "content": "什么是大语言模型?"}
]
  • role字段区分“系统提示”(system)、“用户输入”(user)和“助手回复”(assistant)。
  • 系统提示用于设定模型行为(如“简洁回答”“用中文”)。

对照实验
去掉系统提示后,模型可能生成冗长或不符合要求的回复(如默认用英文回答)。

4. 模板化对话(Template the Conversation)

作用:将对话转换为模型训练时“认识”的格式,核心是添加“生成触发标记”。
代码关键

formatted_text = tokenizer.apply_chat_template(..., add_generation_prompt=True)
  • Qwen模型的模板化结果类似:
    <|SystemBegin|>你是一个简洁的AI助手<|SystemEnd|><|UserBegin|>什么是大语言模型?<|UserEnd|><|AssistantBegin|>
    
  • add_generation_prompt=True会添加<|AssistantBegin|>标记,告诉模型“现在该你回答了”。

对照实验
add_generation_prompt=False,模型会因缺少触发标记而生成混乱内容(如重复用户问题):

# 错误输出(无触发标记时)
什么是大语言模型?什么是大语言模型?我来解释一下...

5. 回复生成(Generate Response)

作用:模型基于输入生成token序列(数字ID)。
代码关键

generated_ids = model.generate(**model_inputs, max_new_tokens=200, temperature=0.7)
  • max_new_tokens:限制生成长度(防止输出过长)。
  • temperature:控制随机性(0.7表示“中等随机”,适合对话)。

对照实验

  • temperature=0:每次生成完全相同的回复(确定性高)。
  • temperature=1.5:生成内容可能天马行空(随机性高)。

6. 解码(Decode the Output)

作用:将模型生成的数字ID转换为人类可读文本。
代码关键

response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)
  • skip_special_tokens=True会去掉<|endoftext|>等模型内部标记,让输出更干净。

对照实验
skip_special_tokens=False,输出会包含冗余标记:

# 带特殊标记的输出
<|AssistantBegin|>大语言模型是...<|endoftext|>

常见问题与解决方案

  1. 生成内容混乱
    原因:模板化步骤缺失(如add_generation_prompt=False)。
    解决:确保apply_chat_templateadd_generation_prompt=True

  2. 回复与问题无关
    原因:系统提示未明确约束(如未指定“用中文回答”)。
    解决:在system角色中增加明确指令(如“严格围绕问题回答,不发散”)。

  3. 生成内容过长/过短
    原因:max_new_tokens参数设置不当。
    解决:根据问题类型调整(如简单问题设为100,复杂问题设为500)。

总结

大语言模型的对话交互是“人类语言→token ID→模型生成→人类语言”的闭环,六个核心步骤缺一不可:

  • 分词器和模型是基础工具,必须匹配;
  • 对话构建和模板化是“翻译”过程,确保模型理解输入;
  • 生成和解码是“输出”过程,控制回复的质量和格式。

理解这套流程后,你可以更灵活地调试模型行为(如通过调整temperature控制回复风格,或通过系统提示约束输出格式),让LLM更好地为特定场景服务。

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐