书生模型实战系列文章目录
第一章 入门岛L0(Linux)
第二章 入门岛L0(python)
第三章 入门岛L0(Git)
提示:以上内容可以看往期文章
第四章 基础岛L1(Demo)
作业
提交作业
作业1–基础任务
作业2–进阶任务
一、执行代码
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
model_name_or_path = "/root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b"
# 分词器加载
tokenizer = AutoTokenizer.from_pretrained(model_name_or_path, trust_remote_code=True, device_map='cuda:0')
#模型加载
model = AutoModelForCausalLM.from_pretrained(model_name_or_path, trust_remote_code=True, torch_dtype=torch.bfloat16, device_map='cuda:0')
model = model.eval()
system_prompt = """You are an AI assistant whose name is InternLM (书生·浦语).
- InternLM (书生·浦语) is a conversational language model that is developed by Shanghai AI Laboratory (上海人工智能实验室). It is designed to be helpful, honest, and harmless.
- InternLM (书生·浦语) can understand and communicate fluently in the language chosen by the user such as English and 中文.
"""
messages = [(system_prompt, '')]
print("=============Welcome to InternLM chatbot, type 'exit' to exit.=============")
while True:
input_text = input("\nUser >>> ")
input_text = input_text.replace(' ', '')
if input_text == "exit":
break
length = 0
for response, _ in model.stream_chat(tokenizer, input_text, messages):
if response is not None:
print(response[length:], flush=True, end="")
length = len(response)
提示:以下是对上述执行代码的一些解读
一、分词器tokenizer 是什么?
直接来看一个案例:
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
model_name_or_path = "/root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b"
tokenizer = AutoTokenizer.from_pretrained(model_name_or_path, trust_remote_code=True, device_map='cuda:0')
# 使用分词器对一段文本进行编码
text = "你好,我正在测试什么是分词器--tokenizer。"
encoded_input = tokenizer(text)
print(encoded_input)
# 获取 token ID
token_ids = encoded_input['input_ids']
# 将 token ID 解码回 token
tokens = tokenizer.convert_ids_to_tokens(token_ids)
for token, token_id in zip(tokens, token_ids):
print(f"Token: {token} \t Token ID: {token_id}")
对应的输出:
{'input_ids': [1, 77230, 60353, 60363, 69202, 69167, 71878, 60402, 61132, 60682, 444, 5994, 3300, 60355], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}
Token: <s> Token ID: 1
Token: 你好 Token ID: 77230
Token: , Token ID: 60353
Token: 我 Token ID: 60363
Token: 正在 Token ID: 69202
Token: 测试 Token ID: 69167
Token: 什么是 Token ID: 71878
Token: 分 Token ID: 60402
Token: 词 Token ID: 61132
Token: 器 Token ID: 60682
Token: -- Token ID: 444
Token: token Token ID: 5994
Token: izer Token ID: 3300
Token: 。 Token ID: 60355
‘input_ids’: 这个列表包含了输入文本经过分词器处理后得到的token ID。每个数字代表一个特定的token,这些token按照原文本的顺序排列。实际的token ID会随着模型的不同而变化,这里的解释是基于一般的语言模型行为。
1: 这通常是特殊标记 [BOS](Beginning Of Sentence)或 [CLS](Classification token),用于表示句子的开始。
‘attention_mask’: 这个列表中的每一个元素都是1,它表示每一个token都是有效的,没有填充。在一些情况下,如果输入的序列长度不足以达到模型要求的最大长度,那么剩下的位置就会被填充,这时对应的注意力掩码值将是0。在这个例子中,由于输入的文本长度正好等于输出的序列长度,因此所有的token都是有效的。
二、模型加载
代码如下(示例):
model = AutoModelForCausalLM.from_pretrained(model_name_or_path, trust_remote_code=True, torch_dtype=torch.bfloat16, device_map='cuda:0')
model = model.eval()
# 输入文本
input_text = "你好,我正在测试什么是分词器--tokenizer。"
# 将文本编码为 token ID
input_ids = tokenizer(input_text, return_tensors='pt').input_ids
print(input_ids)
# 生成文本
output = model.generate(input_ids, max_length=100, num_return_sequences=1)
print(output)
# 解码生成的文本
generated_text = tokenizer.decode(output[0], skip_special_tokens=True)
print(generated_text)
输出结果如下
/root/share/pre_envs/icamp3_demo/bin/python /root/demo/cli_demo.py
Loading checkpoint shards: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:22<00:00, 11.06s/it]
tensor([[ 1, 77230, 60353, 60363, 69202, 69167, 71878, 60402, 61132, 60682,
444, 5994, 3300, 60355]])
tensor([[ 1, 77230, 60353, 60363, 69202, 69167, 71878, 60402, 61132, 60682,
444, 5994, 3300, 60355, 364, 92542, 364, 14511, 262, 69167,
60402, 61132, 60682, 60414, 5994, 3300, 60413, 402, 60361, 69167,
60402, 61132, 60682, 60377, 60353, 61176, 68266, 68880, 87667, 68802,
68264, 60387, 402, 312, 281, 3235, 68865, 60402, 61132, 70538,
68344, 465, 60387, 364, 393, 285, 262, 60402, 61132, 60682,
68971, 69684, 68500, 68270, 60353, 60741, 60530, 68412, 60354, 69684,
71862, 60397, 71628, 60354, 71152, 60535, 72132, 60355, 364, 393,
285, 262, 60741, 69040, 68815, 68519, 68790, 68500, 60414, 304,
12718, 60413, 68565, 60353, 60407, 69684, 69412, 60359, 68347, 71782]])
你好,我正在测试什么是分词器--tokenizer。
### 测试分词器(tokenizer)
在测试分词器时,您需要考虑以下几个关键步骤:
1. **理解分词器的功能**:
- 分词器是一种文本处理工具,它将输入的文本分割成单独的单词或标记。
- 它通常用于自然语言处理(NLP)任务,如文本分类、信息提取
三、在本地主机的 6006 端口上启动应用程序
执行如下代码来启动一个 Streamlit 服务。
streamlit run /root/demo/Tutorial/tools/streamlit_demo.py --server.address 127.0.0.1 --server.port 6006
streamlit_demo.py 部分代码------加载了权重
@st.cache_resource
def load_model():
model = (AutoModelForCausalLM.from_pretrained(
'/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b',
trust_remote_code=True).to(torch.bfloat16).cuda())
tokenizer = AutoTokenizer.from_pretrained(
'/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b',
trust_remote_code=True)
return model, tokenizer
Streamlit 将会在本地的 http://127.0.0.1:6006/ 地址上启动一个Streamlit 应用程序,你可以通过在浏览器中输入这个地址来访问这个应用。
在本地的 PowerShell 中输入以下命令,将端口映射到本地。
ssh -CNg -L 6006:127.0.0.1:6006 root@ssh.intern-ai.org.cn -p 你的 ssh 端口号
在完成端口映射后,我们便可以通过浏览器访问 http://localhost:6006 来启动我们的 Demo。
启动 InternVL2-2B 模型的 Gradio 服务。
conda activate /root/share/pre_envs/icamp3_demo
lmdeploy serve gradio /share/new_models/OpenGVLab/InternVL2-2B --cache-max-entry-count 0.1