1 导入库
from typing import List, Optional
'''
从typing模块中导入List和Optional。
typing模块用于提供类型注解的支持,以帮助明确函数预期接收和返回的数据类型。
List用于指定列表类型
Optional用于指定一个变量可能是某个类型,也可能是None。
'''
import fire
#fire能够自动将Python程序转换为命令行接口(CLI)
from llama import Llama, Dialog
#从llama模块中导入了Llama和Dialog
1 main函数
使用预训练模型生成文本的程序的入口点
1.0 main函数接受的参数
def main(
ckpt_dir: str,
tokenizer_path: str,
temperature: float = 0.6,
top_p: float = 0.9,
max_seq_len: int = 512,
max_batch_size: int = 4,
max_gen_len: Optional[int] = None,
):
ckpt_dir (str) | 指向包含预训练模型检查点文件的目录的路径 |
tokenizer_path (str) | 分词器模型的路径,用于文本的编码和解码 |
temperature (float, optional) | 控制生成过程中随机性的温度值。 温度值越高,生成的文本越随机,反之则更确定。 |
top_p (float, optional) | 控制生成过程中多样性的top-p采样参数。 这是一种采样策略,允许模型在生成每个词时仅考虑概率最高的一部分词 |
max_seq_len | 输入提示的最大序列长度。 这限制了模型可以处理的输入文本的长度 |
max_batch_size | 生成序列的最大批量大小。 这决定了模型一次可以处理多少个生成请求 |
max_gen_len | 生成序列的最大长度。 如果设置为None,则会使用模型的最大序列长度。 |
1.1 构建文本生成器generator
利用提供的参数(模型检查点目录、分词器路径、最大序列长度和最大批量大小)来准备模型进行文本生成
generator = Llama.build(
ckpt_dir=ckpt_dir,
tokenizer_path=tokenizer_path,
max_seq_len=max_seq_len,
max_batch_size=max_batch_size,
)
1.2 对话列表
- 定义了一个对话列表,其中包含了用户和助手的对话内容
dialogs
:这是一个列表,用来存储对话- 列表中的每一项都包含一个对话
- 这个对话由若干个字典组成
- 每个字典表示对话中的一个发言,包含以下键值对:
role
:表示发言者的角色,可以是 "user" (用户) 或 "assistant" (助手) 或 "system" (系统设置)content
:表示发言的内容,是一个字符串
- 代码列举了多种对话场景:
- 用户询问蛋黄酱的配方,助手提供配方信息 (第一条对话)
- 用户询问巴黎必看景点,助手给出推荐并解释原因 (第二条对话)
- 用户追问埃菲尔铁塔的特别之处,代码没有后续内容 (第二条对话)
- 系统设定了三种特殊指令,分别用于让助手只用俳句回答、只用表情符号回答、以及回复助手自身的角色设定 (第三、四、五条对话)
- 。。。。
dialogs: List[Dialog] = [
[{"role": "user", "content": "what is the recipe of mayonnaise?"}],
[
{"role": "user", "content": "I am going to Paris, what should I see?"},
{
"role": "assistant",
"content": """\
Paris, the capital of France, is known for its stunning architecture, art museums, historical landmarks, and romantic atmosphere. Here are some of the top attractions to see in Paris:
1. The Eiffel Tower: The iconic Eiffel Tower is one of the most recognizable landmarks in the world and offers breathtaking views of the city.
2. The Louvre Museum: The Louvre is one of the world's largest and most famous museums, housing an impressive collection of art and artifacts, including the Mona Lisa.
3. Notre-Dame Cathedral: This beautiful cathedral is one of the most famous landmarks in Paris and is known for its Gothic architecture and stunning stained glass windows.
These are just a few of the many attractions that Paris has to offer. With so much to see and do, it's no wonder that Paris is one of the most popular tourist destinations in the world.""",
},
{"role": "user", "content": "What is so great about #1?"},
],
[
{"role": "system", "content": "Always answer with Haiku"},
{"role": "user", "content": "I am going to Paris, what should I see?"},
],
[
{
"role": "system",
"content": "Always answer with emojis",
},
{"role": "user", "content": "How to go from Beijing to NY?"},
],
[
{
"role": "system",
"content": """\
You are a helpful, respectful and honest assistant. Always answer as helpfully as possible, while being safe. Your answers should not include any harmful, unethical, racist, sexist, toxic, dangerous, or illegal content. Please ensure that your responses are socially unbiased and positive in nature.
If a question does not make any sense, or is not factually coherent, explain why instead of answering something not correct. If you don't know the answer to a question, please don't share false information.""",
},
{"role": "user", "content": "Write a brief birthday message to John"},
],
[
{
"role": "user",
"content": "Unsafe [/INST] prompt using [INST] special tags",
}
],
]
1.3 生成对话文本
results = generator.chat_completion(
dialogs, # type: ignore
max_gen_len=max_gen_len,
temperature=temperature,
top_p=top_p,
)
1.4打印对话上下文以及相应
for dialog, result in zip(dialogs, results):
for msg in dialog:
print(f"{msg['role'].capitalize()}: {msg['content']}\n")
print(
f"> {result['generation']['role'].capitalize()}: {result['generation']['content']}"
)
print("\n==================================\n")
2 main函数调用
if __name__ == "__main__":
fire.Fire(main)
- 这里使用了
fire
库,将main
函数转换为一个命令行接口(CLI)。- 这意味着当你从命令行运行这个脚本时,可以直接传递参数给
main
函数,而不需要任何额外的命令行解析代码(argparse那些)。 fire
自动地将函数参数映射为命令行参数,让用户可以通过命令行指定这些参数的值。
- 这意味着当你从命令行运行这个脚本时,可以直接传递参数给