第四节课程简介
讲师:赵文恺
日期:2024.8.1
简介:大语言模型入门
基本概念
大语言模型(LLM)
** 大语言模型(Large Language Model,LLM)是一种基于深度学习技术的人工智能模型,专门用于处理和生成自然语言。它们通常由大量的文本数据训练而成,能够理解和生成与人类语言相关的内容。GPT-4(即我所基于的模型)就是一种大语言模型,能够回答问题、生成文本、进行对话等。**
** 这些模型的基本构建块是神经网络,尤其是变换器(Transformer)架构。它们通过对大量语言数据的学习,掌握了语言的语法、词汇和常识,从而能够生成流畅且符合语境的文本。**
千问2(qwen2)
千问2是阿里云推出的新一代大语言模型,包含多个尺寸的预训练和指令微调模型,如Qwen2-0.5B、Qwen2-1.5B、Qwen2-7B、Qwen2-57B-A14B和Qwen2-72B。这些模型使用了GQA(分组查询注意力)机制,以优化推理速度和显存占用。
Qwen-2 的特点包括:
- 多模态能力:有些版本具备处理文本和图像的能力,能够更好地理解和生成多种形式的信息。
- 开源:Qwen-2 的部分模型和代码可能是开源的,这使得其他开发者和研究人员能够使用和改进这些工具。
- 大规模训练:它通常使用大量的文本数据进行训练,使其在多个语言理解和生成任务中表现良好。
** 本节课我们学习对千问2大语言模型的部署与测试。**
Stable Diffusion图像生成
** Stable Diffusion 是一种强大的图像生成模型,结合了扩散模型的理论和高效的潜在空间操作,使得能够生成高质量和有条件的图像。它在艺术创作、广告、游戏开发等多个领域具有广泛的应用潜力。**


千问2(qwen2)模型
环境准备
我们在趋动云算力平台上进行模型的部署:
注册云算力平台:https://growthdata.virtaicloud.com/t/NA
** 创建项目,选择B1.medium规格服务器**

** 选择CUDA12.1 PyTorch2.1.1的镜像**

** 在模型中搜索Qwen2-0.5B-Instruct**

点击启动后,进入环境。
在/gemini/code中存放代码,/gemini/pretrain中是我们刚刚挂载的模型。
我们在本地解压大模型应用.zip,得到5个文件,进入/gemini/code目录,将文件拖入窗口完成上传。

我们需要安装一些必要的库,确保我们的环境支持模型训练和推理所需的计算负载。
在 Python 环境中更新或安装
transformers
库,
transformers
库是由 Hugging Face 提供的,用于处理和使用各种预训练的深度学习模型,如 BERT、GPT 和其他变换器模型。
!pip install transformers==4.37.0 -U
在 Python 环境中安装 Streamlit 库,Streamlit 是一个用于创建和共享数据应用的开源框架,特别适合快速构建数据科学和机器学习应用的交互式用户界面。
!pip install streamlit
至此,我们完成了前期的环境准备。
test
这段代码的目的是加载一个预训练的因果语言模型,并使用它生成对话回应。
from transformers import AutoModelForCausalLM, AutoTokenizer
device = "cuda" # the device to load the model onto
model = AutoModelForCausalLM.from_pretrained(
"/gemini/pretrain/Qwen2-0.5B-Instruct",
torch_dtype="auto",
device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained("/gemini/pretrain/Qwen2-0.5B-Instruct")
prompt = "你是谁?"
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": prompt}
]
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors="pt").to(device)
generated_ids = model.generate(
model_inputs.input_ids,
max_new_tokens=512
)
generated_ids = [
output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
]
response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
print(respons
我们逐行分析这段代码,解释每行的功能和作用:
from transformers import AutoModelForCausalLM, AutoTokenizer
- 作用:从
transformers库中导入AutoModelForCausalLM和AutoTokenizer。 -AutoModelForCausalLM是 Hugging Face 的transformers库中的一个类,用于自动加载适用于因果语言建模(causal language modeling)的预训练模型。因果语言模型主要用于文本生成任务,比如 GPT(Generative Pre-trained Transformer)系列模型。-AutoTokenizer是 Hugging Face 的transformers库中的一个类,用于自动加载和管理与特定预训练模型兼容的 tokenizer。Tokenizers 是将文本数据转换为模型可以处理的格式的工具,包括将文本转换为 tokens(即模型的输入格式)。
device = "cuda" # the device to load the model onto
- 作用:指定将模型加载到 GPU 上。
"cuda"表示使用 GPU(CUDA 兼容的设备)来加速计算。如果没有 GPU,可将其更改为"cpu"。
model = AutoModelForCausalLM.from_pretrained(
"/gemini/pretrain/Qwen2-0.5B-Instruct",
torch_dtype="auto",
device_map="auto"
)
- 作用:加载一个预训练的因果语言模型。 -
"/gemini/pretrain/Qwen2-0.5B-Instruct"是模型的存储路径(可以是本地路径或模型名称)。-torch_dtype="auto"使得 PyTorch 自动选择适当的数据类型(例如,float32或float16)。-device_map="auto"使得模型自动映射到指定的设备(例如 GPU)。
tokenizer = AutoTokenizer.from_pretrained("/gemini/pretrain/Qwen2-0.5B-Instruct")
- 作用:加载与模型兼容的 tokenizer。
tokenizer用于将文本转换为模型可以处理的格式。
prompt = "你是谁?"
- 作用:定义输入给模型的提示(prompt)。
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": prompt}
]
- 作用:创建一个包含对话上下文的消息列表。 -
"role": "system"指定系统消息,通常用于设置对话的上下文或系统行为。-"role": "user"指定用户消息,表示用户输入的内容(在这里是prompt)。
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)
- 作用:使用 tokenizer 的
apply_chat_template方法将消息列表转换为模型输入格式。 -tokenize=False表示不对模板进行 tokenization。-add_generation_prompt=True表示添加生成提示符,以帮助模型生成更好的回复。
model_inputs = tokenizer([text], return_tensors="pt").to(device)
- 作用:将转换后的文本编码为模型的输入张量,并将其移动到指定的设备(GPU)。
generated_ids = model.generate(
model_inputs.input_ids,
max_new_tokens=512
)
- 作用:使用模型生成文本。 -
model_inputs.input_ids是输入张量。-max_new_tokens=512限制生成的最大新 token 数量为 512。
generated_ids = [
output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
]
- 作用:从生成的 IDs 中删除输入部分,只保留模型生成的部分。 -
zip(model_inputs.input_ids, generated_ids)将输入 IDs 和生成的 IDs 配对。-output_ids[len(input_ids):]表示从生成的 IDs 中删除与输入相同的部分,只保留生成的新部分。
response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
- 作用:将生成的 token IDs 解码为人类可读的文本。 -
skip_special_tokens=True表示跳过特殊 token(如填充和结束标记)。-[0]取出第一个解码的结果(在处理多个输入时,batch_decode返回一个列表)。
print(response)
- 作用:打印生成的响应。
流式输出
** 接下来在test的基础上使用
transformers
库中的模型进行流式文本生成,并处理多轮对话。通过使用线程,模型生成过程不会阻塞主线程,允许实时输出生成的文本。**
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
from threading import Thread
device = "cuda"
model_name = "/gemini/pretrain/Qwen2-0.5B-Instruct"
model = AutoModelForCausalLM.from_pretrained(model_name).to(device)
tokenizer = AutoTokenizer.from_pretrained(model_name)
streamer = TextIteratorStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
messages = [
{"role": "system", "content": "You are a helpful assistant."},
]
/root/miniconda3/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
from .autonotebook import tqdm as notebook_tqdm
Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.
In [2]:
def stream_generate(prompt, model, tokenizer, device):
messages.append({"role": "user", "content": prompt})
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors="pt").to(device)
generate_params = dict(
inputs=model_inputs.input_ids,
max_new_tokens=512,
do_sample=True,
top_k=50,
temperature=0.7,
pad_token_id=tokenizer.eos_token_id,
streamer=streamer
)
thread = Thread(target=model.generate, kwargs=generate_params)
thread.start()
generated_text = ""
for new_text in streamer:
generated_text += new_text
print(new_text, end='', flush=True)
print()
# generated_text
messages.append({"role": "user", "content": generated_text})
In [3]:
# 多轮对话
while True:
user_input = input("User: ")
if user_input.lower() == 'exit':
print("Exiting...")
break
# 生成回复并流式输出
print("Assistant: ", end="")
stream_generate(user_input, model, tokenizer, device)
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
from threading import Thread
import torch:导入 PyTorch 库,用于模型计算和设备管理。from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer:从transformers库导入模型、tokenizer 和流式文本生成工具。from threading import Thread:导入Thread类,用于创建线程,实现异步执行。设置设备和加载模型
streamer = TextIteratorStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
TextIteratorStreamer用于流式生成文本。skip_prompt=True和skip_special_tokens=True控制生成文本的输出格式。
def stream_generate(prompt, model, tokenizer, device):
- 定义一个名为
stream_generate的函数,用于生成模型回复并流式输出。
messages.append({"role": "user", "content": prompt})
将用户输入的消息添加到
messages
列表中,以保持对话上下文。
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)
- 使用
apply_chat_template方法将messages列表转换为模型的输入格式,tokenize=False表示不对文本进行分词,add_generation_prompt=True表示添加生成提示符。
model_inputs = tokenizer([text], return_tensors="pt").to(device)
- 将生成的文本
text转换为 PyTorch 张量,并将其移动到指定的设备(GPU)。
generate_params = dict(
inputs=model_inputs.input_ids,
max_new_tokens=512,
do_sample=True,
top_k=50,
temperature=0.7,
pad_token_id=tokenizer.eos_token_id,
streamer=streamer
)
- 定义生成参数字典: -
inputs=model_inputs.input_ids:模型的输入 ID。-max_new_tokens=512:生成的最大新令牌数。-do_sample=True:启用采样,以产生更随机的输出。-top_k=50:使用前 50 个候选令牌进行采样。-temperature=0.7:控制生成文本的随机性,温度较低生成更确定的输出。-pad_token_id=tokenizer.eos_token_id:填充标记的 ID。-streamer=streamer:用于流式输出的TextIteratorStreamer对象。
thread = Thread(target=model.generate, kwargs=generate_params)
thread.start()
- 创建并启动一个线程来执行模型的生成任务,以避免阻塞主线程。
generated_text = ""
for new_text in streamer:
generated_text += new_text
print(new_text, end='', flush=True)
print()
- 从
streamer获取生成的文本并逐步拼接到generated_text中,同时实时打印生成的文本。
messages.append({"role": "user", "content": generated_text})
- 将生成的文本作为用户消息添加到
messages列表中,以更新对话上下文。
while True:
user_input = input("User: ")
if user_input.lower() == 'exit':
print("Exiting...")
break
- 开启一个无限循环,读取用户输入。如果用户输入
exit,则退出循环并打印"Exiting..."。
print("Assistant: ", end="")
stream_generate(user_input, model, tokenizer, device)
- 调用
stream_generate函数生成回复并流式输出。print("Assistant: ", end="")用于在生成的文本之前打印"Assistant: "提示符。
运行结果

one_chat.py
** 虽然有了流式输出,但是整个问答没有界面,观感差,接下来我们使用streamlit框架构建即时问答系统。**
import streamlit as st
from threading import Thread
import json
import time
from transformers import AutoTokenizer
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
import torch
st.title('Qwen2-0.5B-Instruct')
device = "cuda"
model_name = "/gemini/pretrain/Qwen2-0.5B-Instruct"
@st.cache_resource
def get_model():
model = AutoModelForCausalLM.from_pretrained(model_name).to(device)
tokenizer = AutoTokenizer.from_pretrained(model_name)
return model, tokenizer
model, tokenizer = get_model()
streamer = TextIteratorStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
def generate_response(input_text):
prompt = f'''
你是一个智能问答助手,这是你需要回答的问题:
<question>
{input_text}
</question>
'''
print(prompt)
# 构建消息列表
messages = [{"role": "user", "content": prompt}]
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors="pt").to(device)
generate_params = dict(
inputs=model_inputs.input_ids,
max_new_tokens=512,
do_sample=True,
top_k=50,
temperature=0.7,
pad_token_id=tokenizer.eos_token_id,
streamer=streamer
)
thread = Thread(target=model.generate, kwargs=generate_params)
thread.start()
return streamer
with st.form('my_form'):
text = st.text_area('Enter text:', 'What are the three key pieces of advice for learning how to code?')
submitted = st.form_submit_button('Submit')
if submitted:
message_placeholder = st.empty()
# 调用模型生成响应
streamer = generate_response(text)
response = ""
for text in streamer:
response += text
message_placeholder.info(response + "▌")
message_placeholder.info(response)
import streamlit as st
from threading import Thread
import json
import time
from transformers import AutoTokenizer
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
import torch
导入streamlit库,这是一个用于创建和部署机器学习模型和数据应用程序的Python库。
st是streamlit的简写。导入
Thread类,用于创建线程。导入json库,用于处理json格式的数据。
导入time库,用于处理时间相关的功能。
导入transformers库中的几个类,分别是
AutoModelForCausalLM、AutoTokenizer和TextIteratorStreamer。导入torch库,这是一个用于深度学习的研究和生产级别的Python库。
@st.cache_resource
def get_model():
model = AutoModelForCausalLM.from_pretrained(model_name).to(device)
tokenizer = AutoTokenizer.from_pretrained(model_name)
return model, tokenizer
- 定义了一个函数
get_model,用于加载和返回模型及tokenizer。使用了@st.cache_resource装饰器来缓存模型和tokenizer,以提高性能。
model, tokenizer = get_model()
- 调用
get_model函数,返回模型和tokenizer。
streamer = TextIteratorStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
- 创建一个
TextIteratorStreamer对象,用于流式处理文本数据。skip_prompt=True和skip_special_tokens=True这两个参数用于调整处理过程中的行为。
def generate_response(input_text):
- 定义了一个函数
generate_response,该函数接受一个输入文本input_text,并生成一个相应的响应。
prompt = f'''
你是一个智能问答助手,这是你需要回答的问题:
<question>
{input_text}
</question>
'''
- 定义了一个模板字符串
prompt,将输入的文本input_text嵌入一个结构化的上下文中。
print(prompt)
- 将
prompt打印到控制台。
# 构建消息列表
messages = [{"role": "user", "content": prompt}]
- 构建了一个消息列表
messages,其中包含一个字典,表示用户发送的消息。
text = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)
- 使用
tokenizer.apply_chat_template函数处理消息列表,并将结果赋给text变量。
model_inputs = tokenizer([text], return_tensors="pt").to(device)
- 使用tokenizer将处理过的文本转换为模型的输入格式,并将结果移动到指定的设备上。
generate_params = dict(
inputs=model_inputs.input_ids,
max_new_tokens=512,
do_sample=True,
top_k=50,
temperature=0.7,
pad_token_id=tokenizer.eos_token_id,
streamer=streamer
)
- 定义了生成参数
generate_params字典,包含了模型的输入、生成最大新令牌数、是否进行采样等参数。
thread = Thread(target=model.generate, kwargs=generate_params)
thread.start()
- 创建一个线程,用于异步执行模型的生成任务,并将生成的文本流式输出。
return streamer
- 返回
streamer对象。
with st.form('my_form'):
text = st.text_area('Enter text:', 'What are the three key pieces of advice for learning how to code?')
- 使用streamlit的form组件创建了一个表单
my_form,并提供了文本框供用户输入问题。
submitted = st.form_submit_button('Submit')
- 创建了一个按钮,用于提交表单。
if submitted:
message_placeholder = st.empty()
- 如果表单被提交,则创建一个
message_placeholder以显示输出。
# 调用模型生成响应
streamer = generate_response(text)
- 调用
generate_response生成响应。
response = ""
- 创建了一个空字符串
response,用于存储生成的文本。
for text in streamer:
response += text
message_placeholder.info(response + "▌")
- 遍历
streamer中的文本,将其追加到response中,并实时显示到message_placeholder中。
message_placeholder.info(response)
- 最后,将完整的响应显示到
message_placeholder中。
运行结果


Stable Diffusion
核心概念
- 扩散模型(Diffusion Models): 扩散模型是一类生成模型,通过逐步添加噪声到数据中,然后学习如何从噪声中恢复数据。Stable Diffusion 是这类模型的一个实例。
- 反向扩散过程(Reverse Diffusion Process): 在训练过程中,模型学习如何从噪声恢复图像。这涉及到从纯噪声开始,逐步去噪直到恢复出清晰的图像。
- 条件生成(Conditional Generation): Stable Diffusion 可以根据用户提供的文本描述生成图像,这种条件生成使得模型可以根据指定的文本描述创建相关的图像。
- 潜在空间(Latent Space): Stable Diffusion 在潜在空间中进行操作,这意味着它将图像映射到一个较低维度的空间进行处理,然后再映射回图像空间。这种方法提高了效率,并且生成的图像质量通常较高。
工作原理
- 数据准备和训练: 模型在大量图像和文本对的数据上进行训练。训练的目标是学会如何从图像中添加噪声,并从噪声中恢复出原始图像。
- 文本编码: 使用预训练的文本编码器(如 CLIP)将文本描述编码成潜在空间中的向量。这些向量提供了生成图像的条件信息。
- 生成过程: 从纯噪声开始,模型根据文本描述逐步去噪,生成图像。在每一步中,模型使用已学习的去噪网络来生成图像的细节,直到完成图像的生成。
- 图像解码: 在生成过程结束后,潜在空间中的图像被解码回图像空间,得到最终的图像结果。
环境准备
与千问二环境准备操作类似。


操作应用
在进入环境后输入以下三行命令:
tar xf /gemini/data-1/stable-diffusion-webui.tar -C /gemini/code/
chmod +x /root/miniconda3/lib/python3.10/site-packages/gradio/frpc_linux_amd64_v0.2
cd /stable-diffusion-webui && python launch.py --deepdanbooru --share --xformers --listen
运行结果


总结感想
** 学习千问2.0大语言模型和Stable Diffusion,是一种梦幻般的体验,它不仅让我深入了解了当前AI领域的两大热点技术,也让我对人工智能的潜力和未来有了更深刻的认识。**
** 首先,千问2.0大语言模型给我留下了深刻的印象。这款先进的模型,不仅在自然语言处理方面的表现令人惊叹,而且它的应用范围之广、功能之强,都让人叹为观止。它不仅仅是一个信息检索工具,更是一个能够理解和生成自然语言的智能系统,它不仅能回答问题,还能进行创作、翻译、摘要等复杂任务。这让我深刻感受到了人工智能在学习和工作效率上的提升潜力,同时对于如何更好地与这种智能系统交互,也有了更多的思考。**
** 而Stable Diffusion,则以其惊人的图像生成能力,让我对这个由人类使用工具改造世界的传统观念产生了疑问。过去,媒介和技法是制作艺术作品的限制,而现在,这些门槛被AI技术所打破。它可以读懂你的文字描述,并将其转化为令人信服的视觉图像。这种技术力量的展现,不仅让艺术家们对创作有了新的思考,也让我们普通人感受到了创造力的解放。**
** 两者的结合,更是让人激动。当强大的语言模型与图像生成技术相结合,可以想象得到,未来无论是科技产品设计、游戏开发,还是影视制作、艺术创作,都将迎来一场前所未有的革命。我们已经见到了诸如文本到图像(Text-to-Image)生成的初步应用,这仅仅是冰山一角。随着技术的不断发展和应用,我们可以预见,未来可能会有更多的creative work,是由智能系统辅助甚至完全由智能系统独立完成的。**
** 但与此同时也带来了一些问题和挑战。比如在版权、伦理和技术偏见等方面。我们如何确保这些技术的发展和应用符合社会伦理和法律规范?在AI生成内容的背后,作者和创作者的角色又如何界定?这些是我们在享受新技术带来便利的同时,必须认真考虑的问题。**
** 总之,虽然这些技术还在不断的成长和完善之中,但它们无疑已经为我们打开了通往美好未来的一扇窗。作为一个学习者,我感到非常激动,同时也感到了责任重大。未来,我要继续努力学习,不断探索,希望能在这些领域贡献自己的力量,共同创造一个更加智能化、更加美好的世界。**
版权归原作者 siriusj19 所有, 如有侵权,请联系我们删除。