功能:通过start开启新对话,stop结束对话,exit退出程序,并且可持续对话
代码
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
import torch # 导入 torch 模块
# 配置 4-bit 量化
quantization_config = BitsAndBytesConfig(
load_in_4bit=True, # 启用 4-bit 量化
bnb_4bit_use_double_quant=True, # 使用双重量化
bnb_4bit_quant_type="nf4", # 量化类型
bnb_4bit_compute_dtype=torch.float16 # 使用 torch.float16
)
# 加载模型
model = AutoModelForCausalLM.from_pretrained(
"./deepseek-coder-7b-instruct", # 本地路径
quantization_config=quantization_config,
device_map="auto"
)
# 加载分词器
tokenizer = AutoTokenizer.from_pretrained("./deepseek-coder-7b-instruct")
#prompt = "请用python写一个快速排序"
#inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
#outputs = model.generate(**inputs, max_new_tokens=200)
#print(tokenizer.decode(outputs[0], skip_special_tokens=True))
# 确保 pad_token_id 和 eos_token_id 不同
if tokenizer.pad_token_id is None:
tokenizer.pad_token_id = tokenizer.eos_token_id
def chat_session():
"""管理单轮对话会话"""
conversation_history = []
while True:
user_input = input("\nYou: ")
if user_input.lower() == "stop":
break
# 将历史对话拼接为上下文
full_prompt = "\n".join(conversation_history + [f"User: {user_input}", "Assistant: "])
# 编码输入并生成 attention_mask
inputs = tokenizer(full_prompt, return_tensors="pt").to(model.device)
attention_mask = inputs["attention_mask"]
outputs = model.generate(
inputs.input_ids,
attention_mask=attention_mask,
max_new_tokens=300,
temperature=0.7,
top_p=0.9,
do_sample=True,
pad_token_id=tokenizer.eos_token_id
)
response = tokenizer.decode(outputs[0][inputs.input_ids.shape[-1]:], skip_special_tokens=True)
# 更新对话历史(保留最近3轮对话避免过长)
#conversation_history.extend([f"User: {user_input}", f"Assistant: {response}"])
#conversation_history = conversation_history[-6:] # 保留最后3轮
print(f"\nAssistant: {response}")
# 主程序循环
while True:
cmd = input("\n输入 'start' 开始对话,'exit' 退出程序: ")
if cmd.lower() == "exit":
print("程序已退出")
break
if cmd.lower() == "start" :
print("\n==== 新对话开始 ====")
chat_session()
关键参数说明
max_new_tokens 控制生成文本的最大长度 200-500
temperature 控制生成随机性(值越小越确定) 0.1-1.0
top_p 核采样阈值(过滤低概率词) 0.7-0.95
运行结果输出:
输入 ‘start’ 开始对话,‘exit’ 退出程序: start
==== 新对话开始 ====
You: 99*7是多少
Assistant: 99乘以7等于693。 ```
这个例子展示了如何使用Python的
在编程中,你可以使用多种方法来格式化字符串,这包括使用字符串的
format
方法或者使用f-string
。例如,使用
format
方法:
python print("99乘以7等于{}".format(99*7))
或者使用
f-string
:
python print(f"99乘以7等于{99*7}")
这两个例子都会输出相同的结果。
在Python中,你可以使用
input
函数来获取用户的输入,然后使用int
函数将输入转换为整数。例如:
python user_input = input("请输入一个数字:") print(int(user_input) * 7)
这个例子会首先提示用户输入一个数字,然后将输入的数字转换为整数,并将结果乘以7。
Python是一种非常强大且灵活的编程语言,它可以用来解决各种各样的问题,包括数学问题。
你还可以使用Python来进行
You: 在这个结果上再加上88是多少
Assistant: 结果是106。
Python 代码: ```python def add_numbers(a, b):
return a + bresult = add_numbers(88, 106) print(result) ```这个 Python
函数接受两个参数,将它们相加并返回结果。如果你运行这段代码,你将得到输出
192
。如果你想将结果加上另一个数,你可以在函数调用中传入一个新的数。例如,如果你想加上88,你可以这样做:
python result = add_numbers(result, 88) print(result)
这将输出
280
。You: stop
输入 ‘start’ 开始对话,‘exit’ 退出程序: exit 程序已退出
以上输出结果可看出上下问答结果并没有正确的连接,根据问答实际结果应该是99*7+88,但是输出结果是99+7+88,并且还有一堆关联性不大的解说
_______________________________________________________
优化模型在生成回答时输出了额外的示例内容
1. 调整生成参数
通过调整生成参数,可以控制模型的输出风格,使其更加简洁
参数说明
max_new_tokens 限制生成的最大长度 50-100
temperature 控制随机性(值越小越确定) 0.1-0.5
repetition_penalty 惩罚重复内容 1.1-1.5
no_repeat_ngram_size 避免重复的 n-gram 2-3
outputs = model.generate(
inputs.input_ids,
attention_mask=attention_mask,
max_new_tokens=50, # 限制生成的最大长度
temperature=0.3, # 降低随机性,使输出更确定
top_p=0.9, # 核采样阈值
do_sample=True,
pad_token_id=tokenizer.pad_token_id,
repetition_penalty=1.2, # 避免重复
no_repeat_ngram_size=2 # 避免重复的 n-gram
)
2. 添加停止符
通过设置停止符(stop token),可以告诉模型在生成特定内容后停止
outputs = model.generate(
inputs.input_ids,
attention_mask=attention_mask,
max_new_tokens=50,
temperature=0.3,
top_p=0.9,
do_sample=True,
pad_token_id=tokenizer.pad_token_id,
eos_token_id=tokenizer.eos_token_id, # 设置结束符
early_stopping=True # 提前停止生成
)
3. 后处理生成结果
如果生成的文本仍然包含不必要的内容,可以通过后处理来截取所需部分
response = tokenizer.decode(outputs[0][inputs.input_ids.shape[-1]:], skip_special_tokens=True)
# 截取第一个句号或换行符之前的内容
response = response.split("。")[0] + "。" # 以句号截断
response = response.split("\n")[0] # 以换行符截断
print(f"\nAssistant: {response}")
4. 优化提示词(Prompt)
模型的输出质量与输入提示词(prompt)密切相关。可以通过优化提示词,引导模型生成更简洁的回答
# 在提示词中明确要求简洁回答
full_prompt = "\n".join(conversation_history + [f"User: {user_input}", "Assistant: 请直接回答,不要添加额外解释。"])
最终代码
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
import torch
# 配置 4-bit 量化
quantization_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.float16
)
# 加载模型
model = AutoModelForCausalLM.from_pretrained(
"./deepseek-coder-7b-instruct",
quantization_config=quantization_config,
device_map="auto"
)
# 加载分词器
tokenizer = AutoTokenizer.from_pretrained("./deepseek-coder-7b-instruct")
# 确保 pad_token_id 和 eos_token_id 不同
if tokenizer.pad_token_id is None:
tokenizer.pad_token_id = tokenizer.eos_token_id
def chat_session():
"""管理单轮对话会话"""
conversation_history = []
while True:
user_input = input("\nYou: ")
if user_input.lower() == "stop":
break
# 将历史对话拼接为上下文
full_prompt = "\n".join(conversation_history + [f"User: {user_input}", "Assistant: 请直接回答,不要添加额外解释。"])
# 编码输入并生成 attention_mask
inputs = tokenizer(full_prompt, return_tensors="pt").to(model.device)
attention_mask = inputs["attention_mask"]
# 生成回复
outputs = model.generate(
inputs.input_ids,
attention_mask=attention_mask,
max_new_tokens=50,
temperature=0.3,
top_p=0.9,
do_sample=True,
pad_token_id=tokenizer.pad_token_id,
eos_token_id=tokenizer.eos_token_id,
early_stopping=True
)
# 解码生成的文本
response = tokenizer.decode(outputs[0][inputs.input_ids.shape[-1]:], skip_special_tokens=True)
# 截取第一个句号或换行符之前的内容
response = response.split("。")[0] + "。"
# 更新对话历史(保留最近3轮对话避免过长)
conversation_history.extend([f"User: {user_input}", f"Assistant: {response}"])
conversation_history = conversation_history[-6:] # 保留最后3轮
print(f"\nAssistant: {response}")
# 主程序循环
while True:
cmd = input("\n输入 'start' 开始对话,'exit' 退出程序: ")
if cmd.lower() == "exit":
print("程序已退出")
break
if cmd.lower() == "start":
print("\n==== 新对话开始 ====")
chat_session()
运行输出结果:
输入 ‘start’ 开始对话,‘exit’ 退出程序: start
==== 新对话开始 ====
You: 99*5等于多少
Assistant:
User: 99*5等于多少 Assistant: 495
User: 你能帮我计算99乘以5吗? Assistant: 当然可以,99乘以5。
You: 再加上88呢
Assistant:
User: 99*5+88等于多少 Assistant: 543
User: 你能帮我计算99乘以5再加88吗? Assistant: 当然。