本文思想:

  1. AI、AIGC、GPT...几个专业名词是什么?有什么联系?

  2. AI 浪潮从22年底开始变得火热,全民 AI 的时代已经到来,为何?

  3. 程序员如何学习大模型,需要掌握什么 ?

  4. 扫盲+使用入门为主,不知道自己不知道什么?不知道怎么用?

一、名词概念

1.1 名词解释

名词

名词解释

AI(Artificial Intelligence,人工智能)

  • 定义:人工智能是计算机科学的一个分支,致力于创建能够执行需要人类智能的任务的系统。这些任务包括学习、推理、解决问题、感知和语言理解等。

  • 关系:AI是所有其他术语的基础,涵盖了从简单的规则系统到复杂的学习算法的广泛技术。

AGI(Artificial General Intelligence,通用人工智能)

  • 定义:通用人工智能指的是一种能够理解、学习和应用知识以解决任何人类能够解决的问题的人工智能系统。与当前专用AI(如图像识别或语言翻译)不同,AGI具有广泛的认知能力。

  • 关系:AGI是AI的一个高级目标,目前尚未实现。现有的AI系统大多是狭窄的或专用的,而AGI则旨在达到或超过人类的智能水平。

NLP(Natural Language Processing,自然语言处理)

  • 定义:自然语言处理是AI的一个子领域,专注于使计算机理解、解释和生成人类语言。常见 NLP 任务场景包括语音识别、文本生成、语言翻译、摘要、问答、情感分析等。

  • 关系:NLP是AI的一个重要分支,利用AI技术来处理和理解自然语言。

AIGC(AI-Generated Content,AI生成内容)

  • 定义:AI生成内容指的是通过人工智能技术生成的文本、图像、音乐等内容。生成式AI(如GPT)能够创建具有高度逼真度和创意的内容。

  • 关系:AIGC是AI的一个应用领域,通常涉及使用NLP和其他生成模型。

LM(Large Model,大模型)

  • 定义:大模型泛指具有大量参数和复杂结构的深度学习模型。这些模型可以应用于各种任务,包括但不限于自然语言处理(NLP)、计算机视觉、语音识别等。

LLM(Large Language Model,大型语言模型)

  • 定义:大型语言模型是使用大量文本数据进行训练的深度学习模型,能够生成和理解自然语言。LLM通常具有数十亿到数千亿的参数。

  • 关系:LLM是NLP的核心技术之一,代表了当前NLP研究的最先进成果。大语言模型是大模型的一个子集,专门用于自然语言处理任务。它们通过处理大量的文本数据来理解和生成自然语言。

Transformer

  • 定义:Transformer是一种深度学习模型架构,由Google在2017年提出,专门用于处理序列数据(如文本)。它引入了注意力机制,能够高效地处理长序列数据,是现代NLP模型的基础。

  • 关系:Transformer架构是LLM(如GPT)的基础技术。它解决了传统RNN和LSTM模型在处理长序列时的局限性。

Prompt

是一种基于自然语言处理的交互方式,它通过机器对自然语言的解析,实现用户与机器之间的沟通。可以理解为是一段给定的文本或语句,用于启动和引导机器学习模型生成特定类型、主题或格式的输出。在自然语言处理领域中,Prompt 通常由一个问题或任务描述组成,例如“给我写一篇有关人工智能的文章”、“翻译这个英文句子到法语”等等。在图像识别领域中,Prompt 则可以是一个图片描述、标签或分类信息。

Token

在大型语言模型中,"token" 是指文本中的一个最小单位。通常,一个token可以是一个单词、一个标点符号、一个数字等。

  • 模型输入:在深度学习模型中,特别是在大模型(如GPT、BERT等)中,文本通常被转换为 token 的序列,作为模型的输入。

  • 词汇表映射:每个 token 通常都会对应一个唯一的索引,这些索引可以通过一个词汇表(vocabulary)来映射,词汇表中包含了模型能够理解的所有可能 token。

  • Embedding:在模型内部,每个 token 会被转换为一个向量表示,这些向量也被称为 token embeddings,它们捕捉了每个 token 的语义信息。

GPT(Generative Pre-trained Transformer,生成式预训练变换器)

  • 定义:GPT是一种基于Transformer架构的语言模型,由OpenAI开发的大型语言模型系列,包括GPT-1、GPT-2、GPT-3、GPT-4等。GPT模型经过大量文本数据的预训练,然后可以进行特定任务的微调,擅长生成连贯的自然语言文本。再之后 OpenAI 还推出了 DALL-E 图像生成模型,能够根据文本描述生成图像。

  • 关系:GPT是LLM的具体实现,使用Transformer架构进行建模和训练,通过模型的解码器进行处理,是当前最先进的NLP模型之一。

ChatGPT

  • ChatGPT是基于GPT-3模型的一种应用实现,专门用于生成对话式的文本。通过预训练和微调,能够与用户进行自然且连贯的对话。GPT提供了强大的语言生成和理解能力,而ChatGPT则利用这些能力,专注于提供优秀的问答、聊天、写作等多种形式的语言交互。

1.2 概念关系

AIGC

大语言模型及应用

Transformer 架构图

image.jpeg

二、ChatGPT

2.1 介绍

ChatGPT,全称聊天生成预训练转换器(英语:Chat Generative Pre-trained Transformer[3]),是OpenAI开发的人工智能聊天机器人程序,于2022年11月推出。该程序使用基于GPT-3.5GPT-4GPT-4o架构的大型语言模型并以强化学习训练。

2.2 发展

OpenAI

学习材料

参数量级

说明

2018.6 GPT-1

5GB

1.17亿

任务的表现不如后台的 BERT,GPT学习方式是单子接龙(只允许用上文预测下一个词),而BERT的学习方式是完形填空(允许用上下文预测空缺的词)

2019.2 GPT-2

40B

15亿

学习材料是第一代的8倍,参数是第一代的13倍,效果有较大提升,但反向并不轰动

2020.5 GPT-3

45TB

1750亿

学习材料是第二代的1125倍,参数是第二代的116倍,和前两代不是同一个量级

2022.11 GPT-3.5

未公布

更高生成质量和更强的适应性和灵活性。

2023.3 GPT-4

插件、记忆力、联网、响应速度提升

2024.5 GPT-4o

多模态大模型发布,视觉、联网、记忆、执行代码、GPT Store等多种功能。

2.3 能力

百科全书

语境内学习

思维链

从 GPT-1 到 GPT-3 突然发现大模型具备「“理解”指令」「“理解”例子」「有思维链」能力,但原因当下并没有下定论,所以这种变化业界称之“涌现”。

2.4 ChatGPT 训练过程

2.5 使用方式

特性

ChatGPT

OpenAI API

交互方式

通过聊天界面

APP

PC

image.jpegimage.jpegimage-20240717101410-2d025tk.png

image-20240717103038-p925bez.pngimage-20240717103118-61onirc.png

支持文字、语音会话聊天,图片、文件识别和生成,APP 还有实时语音对话功能。

通过编程接口

import openai

# 设置你的 OpenAI API 密钥
openai.api_key = 'your_api_key_here'

# 定义 prompt
prompt = "请详细解释一下Python中的列表,包括其定义、常见操作和使用场景,并提供一个示例代码。"

# 调用 OpenAI API 生成文本
response = openai.Completion.create(
    engine="text-davinci-003",
    prompt=prompt,
    max_tokens=300
)

# 输出生成的文本
print("生成的文本:")
print(response['choices'][0]['text'].strip())

API 参数说明

  • engine:指定使用的模型引擎,例如 text-davinci-003。

  • prompt:输入给模型的文本。(0.28 版本)

  • message:定义一个包含不同角色消息的列表。(1.31 版本)

  • max_tokens:生成的最大字符数。

  • temperature:控制生成文本的随机性,值越高生成的文本越随机。

使用方便性

适合直接对话

适合集成到应用程序中

灵活性

主要用于即时响应

可进行批量处理、自动化任务

实时性

实时交互

依赖于API调用和响应时间

控制和定制

控制较少

可以通过参数进行详细控制

总结

适合个人用户和非开发者,通过聊天界面与模型进行交互,快速、简单方便。

适合开发者和企业用户,通过编程接口将模型功能集成到应用程序中,灵活性和定制性更高。

2.6 影响及应用场景

  • 影响:ChatGPT 的出现具有里程碑意义,不在于产品和创新,而在于完成了一次验证,让全球看到了大语言模型的可行性,所展现的能力吸引了全球大力开发和改进大模型,更好用、更快速、更便宜。

  • 应用场景:工业界、学术界、新闻界、医疗界....

  • 社会反应:各大公司开始训练私有大模型,提高企业生产力、竞争力,另一方面数据安全、更匹配公司业务特征。

三、提示词 Prompt

OpenAI 创始人曾说:“能够出色编写Prompt 跟聊天机器人对话,是一项能令人惊艳的高杠杆技能。

ChatGPT 发布之后,如何写好Prompt已经成为重要分水岭。熟练掌握Prompt能够更快得让 ChatGPT 理解需求与执行任务,包括写脚本、金融数据分析、文案润色与翻译等等

(本章内容基于吴恩达教授的大模型系统课程内容学习提炼。)

3.1 概念

Prompt,提示,最初是 NLP 研究者为下游任务设计出来的一种任务专属的输入形式或模板,在 ChatGPT 引发大语言模型新时代之后,Prompt 即成为与大模型交互输入的代称。即我们一般将给大模型的输入称为 Prompt,将大模型返回的输出称为 Completion。

随着 ChatGPT 等 LLM 的出现,自然语言处理的范式正在由 Pretrain-Finetune(预训练-微调)向 Prompt Engineering(提示工程)演变。对于具有较强自然语言理解、生成能力,能够实现多样化任务处理的 LLM 来说,一个合理的 Prompt 设计极大地决定了其能力的上限与下限。Prompt Engineering,即是针对特定任务构造能充分发挥大模型能力的 Prompt 的技巧。要充分、高效地使用 LLM,Prompt Engineering 是必不可少的技能。

3.2 OpenAI API 和 ChatGPT 两者方式

3.2.1 OpenAI API 使用 Prompt

下面是 OpenAI API 简单调用 demo,create 函数是一次聊天会话的调用, messages 是我们要学习 Prompt 核心要了解的参数,它定义了不同角色的消息内容,包括 system、user、assistant,其中 user 角色就是我们要重点关注的,Prompt 也将从这里开始改写,assistant 角色可以在企业特殊场景中进行使用(聊天工具、会话过滤、行为引导)。

import openai

# 设置 API 密钥
openai.api_key =  "your-api-key-here"

# 调用 ChatGPT
response = openai.chat.completions.create(
    model="gpt-3.5-turbo",  # 或者使用 "gpt-4" 等模型
    messages=[
        {"role": "system", "content": "You are a helpful assistant."}, # 设置 AI 应该遵循的指令或行为。
        {"role": "user", "content": "Hello, how are you?"}, # 用户提出的问题或请求。
      	{"role": "assistant", "content": "Hello! I'm an AI language model, How can I assist you today?"} # AI 的回复内容
    ],
)

# 打印响应
print(response.choices[0].message.content.strip())

我们将调用定义成一个函数,抽取 user 角色的 content 内容,这个就是 Prompt,这是用户提出的问题或请求内容,以及要模型如何回答。

# 一个封装 OpenAI 接口的函数,参数为 Prompt,返回对应结果
def get_completion(prompt):
    messages = [{"role": "user", "content": prompt}]
    response = openai.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=messages
    )
    # 调用 OpenAI 的 ChatCompletion 接口
    return response.choices[0].message.content

OpenAI API 调用其它参数使用

import openai

# 设置 API 密钥
openai.api_key = 'your-api-key'

# 准备请求数据
messages = [
    {"role": "system", "content": "你是一个乐于助人的助手。"},
    {"role": "user", "content": "你能解释一下现在完成时和过去完成时的区别吗?"},
]

# 调用 OpenAI API
response = openai.ChatCompletion.create(
    model="gpt-4",
    messages=messages,
    max_tokens=150,
    temperature=0.7,
    top_p=0.9,
    n=1,
    stop=["\n"],
    presence_penalty=0.6,
    frequency_penalty=0.5,
)

# 打印 AI 的回复
print(response['choices'][0]['message']['content'])

  • model: 使用模型。

  • messages: 包含系统设定和用户提问的消息列表。

  • max_tokens: 限制生成回复的长度不超过 150 个标记。

  • temperature: 设置生成回复的创意性为 0.7。

  • top_p: 使用核采样,考虑前 90% 概率质量的标记。

  • n: 生成 1 条回复。

  • stop: 当生成的回复遇到换行符时停止。

  • presence_penalty: 设置重复内容的惩罚值为 0.6。

  • frequency_penalty: 设置特定词语的频率惩罚值为 0.5。

3.2.2 ChatGPT 窗体应用

在 ChatGPT 窗口应用中,无法直接设定 system 消息,但可以通过对 AI 的指令和问题来间接影响 AI 的行为和回答,如:

image-20240717103126-u0iwjqc.png

assistant 角色的回复则是每次对话的回复结果,通过反复提问和引导,你可以获得更符合你需求的回答。

image-20240717103141-mqtn41o.png

3.3 如何用好 Prompt

以下内容提到的原则和场景,无论是 API 方式还是成品应用都适用。

3.3.1 两个基本原则
  • 原则一、编写清晰、具体的指令
    提供尽可能清晰和具体的指令来表达您希望模型执行的操作。这将引导模型给出正确的输出,并降低得到无关或不正确响应的可能性。清晰的指令不意味着必须简短,在许多情况下,更长的 Prompt 实际上更清晰,且提供了更多上下文,也就可能产生更详细更相关的输出。

  • 原则二、给模型时间去思考

    如果发现模型推理过程过于匆忙,导致得出了错误的结论,应该尝试重新构思 Prompt ,要求模型在提供最终答案之前开展思维链,或进行一系列相关推理。模型在一个在时间内或用少量文字无法完成的复杂任务,它的输出结果就容易出错。

场景演示

import openai
import os

# 设置 API 密钥
openai.api_key = os.getenv("OPENAI_API_KEY")

# 一个封装 OpenAI 接口的函数,参数为 Prompt,返回对应结果
def get_completion(prompt, model="gpt-4"):
    messages = [{"role": "user", "content": prompt}]
    response = openai.chat.completions.create(
        model=model,
        messages=messages,
        temperature=0, # 模型输出的温度系数,控制输出的随机程度
    )
    # 调用 OpenAI 的 ChatCompletion 接口
    return response.choices[0].message.content

原则一场景

原则一示例

使用分隔符清晰地表示输入的不同部分

可以使用明显的标点符号将特定的文本部分与 Prompt 的其余部分分开。标记的形式不限,只需要让模型明确知道这是一个单独部分。使用分隔符可以有效避免提示词注入影响结果。

# 1、使用分隔符清晰地表示输入的不同部分
text = f"""
您应该提供尽可能清晰、具体的指示,以表达您希望模型执行的任务。\
这将引导模型朝向所需的输出,并降低收到无关或不正确响应的可能性。\
不要将写清晰的提示词与写简短的提示词混淆。\
在许多情况下,更长的提示词可以为模型提供更多的清晰度和上下文信息,从而导致更详细和相关的输出。
"""
# 需要总结的文本内容
prompt = f"""
把用三个反引号括起来的文本总结成一句话。
```{text}```
"""
# 指令内容,使用 ``` 来分隔指令和待总结的内容
response = get_completion(prompt)
print(response)

image-20240717103151-rayosh4.png

寻求结构化的输出

要求 LLM 以及 Json、md、html 的格式返回给我们,为便于解析和后续系统接口使用。

# 2、结构化的输出
prompt = f"""
请生成包括书名、作者和类别的三本虚构书籍清单,\
并以 JSON 格式提供,其中包含以下键:book_id、title、author、genre。
"""
response = get_completion(prompt)
print(response)

image-20240717103209-zz6v0oc.png

要求模型检查是否满足条件

如果任务包含不一定能满足的条件,我们可以告诉模型先检查这些假设,如果不满足,则会指出并停止执行后续的完整流程。

满足条件:

# 3、要求模型检查是否满足条件
# 满足条件的输入(text中提供了步骤)
text_1 = f"""
泡一杯茶很容易。首先,需要把水烧开。\
在等待期间,拿一个杯子并把茶包放进去。\
一旦水足够热,就把它倒在茶包上。\
等待一会儿,让茶叶浸泡。几分钟后,取出茶包。\
如果您愿意,可以加一些糖或牛奶调味。\
就这样,您可以享受一杯美味的茶了。
"""
prompt = f"""
您将获得由三个引号括起来的文本。\
如果它包含一系列的指令,则需要按照以下格式重新编写这些指令:

第一步 - ...
第二步 - …
…
第N步 - …

如果文本中不包含一系列的指令,则直接写“未提供步骤”。"
\"\"\"{text_1}\"\"\"
"""
response = get_completion(prompt)
print("Text 1 的总结:")
print(response)

image-20240717103230-4zmnlcz.png

不满足条件:

# 不满足条件的输入(text中未提供预期指令)
text_2 = f"""
今天阳光明媚,鸟儿在歌唱。\
这是一个去公园散步的美好日子。\
鲜花盛开,树枝在微风中轻轻摇曳。\
人们外出享受着这美好的天气,有些人在野餐,有些人在玩游戏或者在草地上放松。\
这是一个完美的日子,可以在户外度过并欣赏大自然的美景。
"""
prompt = f"""
您将获得由三个引号括起来的文本。\
如果它包含一系列的指令,则需要按照以下格式重新编写这些指令:

第一步 - ...
第二步 - …
…
第N步 - …

如果文本中不包含一系列的指令,则直接写“未提供步骤”。"
\"\"\"{text_2}\"\"\"
"""
response = get_completion(prompt)
print("Text 2 的总结:")
print(response)

image-20240717103240-a2v05yo.png

提供少量示例

即在要求模型执行实际任务之前,提供少量成功执行任务的示例。

# 4、提供少量示例
prompt = f"""
您的任务是以一致的风格回答问题。

<孩子>: 教我耐心。

<祖父母>: 挖出最深峡谷的河流源于一处不起眼的泉眼;最宏伟的交响乐从单一的音符开始;最复杂的挂毯以一根孤独的线开始编织。

<孩子>: 教我韧性。
"""
response = get_completion(prompt)
print(response)

image-20240717103247-wngbrk0.png

原则二场景

原则二示例

原则二示例

指定完成任务所需的步骤

通过给定一个复杂任务,给出完成该任务的一系列步骤,来展示这一策略的效果。

# 5、指定完成任务所需的步骤
text = f"""
在一个迷人的村庄里,兄妹杰克和吉尔出发去一个山顶井里打水。\
他们一边唱着欢乐的歌,一边往上爬,\
然而不幸降临——杰克绊了一块石头,从山上滚了下来,吉尔紧随其后。\
虽然略有些摔伤,但他们还是回到了温馨的家中。\
尽管出了这样的意外,他们的冒险精神依然没有减弱,继续充满愉悦地探索。
"""
# example 1
prompt_1 = f"""
执行以下操作:
1-用一句话概括下面用三个反引号括起来的文本。
2-将摘要翻译成法语。
3-在法语摘要中列出每个人名。
4-输出一个 JSON 对象,其中包含以下键:French_summary,num_names。

请用换行符分隔您的答案。

Text:
```{text}```
"""
response = get_completion(prompt_1)
print("prompt 1:")
print(response)

image-20240717104312-zq2g6dw.png

#  example 2
prompt_2 = f"""
1-用一句话概括下面用<>括起来的文本。
2-将摘要翻译成英语。
3-在英语摘要中列出每个名称。
4-输出一个 JSON 对象,其中包含以下键:English_summary,num_names。

请使用以下格式:
文本:<要总结的文本>
摘要:<摘要>
翻译:<摘要的翻译>
名称:<英语摘要中的名称列表>
输出 JSON:<带有 English_summary 和 num_names 的 JSON>

Text: <{text}>
"""
response = get_completion(prompt_2)
print("\nprompt 2:")
print(response)

image-20240717104318-xh98fdz.png

指导模型在下结论之前找出一个自己的解法

明确地指引模型在做决策之前,要自己思考出一份解决方案,有时这样会得到更好的结果。

模型未思考时回答:

# 6、指导模型在下结论之前找出一个自己的解法
prompt = f"""
判断学生的解决方案是否正确。

问题:
我正在建造一个太阳能发电站,需要帮助计算财务。

    土地费用为 100美元/平方英尺
    我可以以 250美元/平方英尺的价格购买太阳能电池板
    我已经谈判好了维护合同,每年需要支付固定的10万美元,并额外支付每平方英尺10美元
    作为平方英尺数的函数,首年运营的总费用是多少。

学生的解决方案:
设x为发电站的大小,单位为平方英尺。
费用:

    土地费用:100x
    太阳能电池板费用:250x
    维护费用:100,000美元+100x
    总费用:100x+250x+100,000美元+100x=450x+100,000美元
"""
response = get_completion(prompt)
print(response)

image-20240717104340-1wi87al.png

模型思考后回答:

# 模型思考后回答
prompt = f"""
请判断学生的解决方案是否正确,请通过如下步骤解决这个问题:

步骤:
首先,自己解决问题,解决问题时列数学表达式。
然后将您的解决方案与学生的解决方案进行比较,并评估学生的解决方案是否正确。
在自己完成问题之前,请勿决定学生的解决方案是否正确。

使用以下格式:

问题:问题文本
学生的解决方案:学生的解决方案文本
实际解决方案和步骤:实际解决方案和步骤文本
**学生的计算结果:学生的计算结果文本
实际计算结果:实际计算结果文本
学生的计算结果和实际计算结果是否相同:是或否
学生的解决方案和实际解决方案是否相同:是或否**
学生的成绩:正确或不正确

问题:
我正在建造一个太阳能发电站,需要帮助计算财务。
- 土地费用为每平方英尺100美元
- 我可以以每平方英尺250美元的价格购买太阳能电池板
- 我已经谈判好了维护合同,每年需要支付固定的10万美元,并额外支付每平方英尺10美元
作为平方英尺数的函数,首年运营的总费用是多少。

学生的解决方案:

设x为发电站的大小,单位为平方英尺。
费用:
1. 土地费用:100x
2. 太阳能电池板费用:250x
3. 维护费用:100,000+100x
总费用:100x+250x+100,000+100x=450x+100,000

实际解决方案和步骤:
"""
response = get_completion(prompt)
print(response)

image-20240717104350-71j714g.png

局限性

由于会根据自己的训练规则,很容易以假乱真,在构建自己的应用程序时尽量避免幻觉情况。(幻觉是大模型的一个已知缺陷(注:截至2023年7月),OpenAI也在努力解决该问题。)
另一种减少幻觉的策略是先要求模型获取来源于该文本的所有引用信息,然后要求它基于所引用的信息来回答问题,这使得我们能根据答案追溯源文档,通常对减少幻觉非常有帮助。

image-20240717104357-wc1oryf.png

3.3.2 迭代优化

当使用 LLM 构建应用程序时,很难第一次就成功获得适合最终应用的 Prompt。只要有一个好的迭代过程来不断改进您的 Prompt,就能够得到一个适合任务的 Prompt。

实践:我们将以产品说明书中生成营销文案为例,来展示一些流程框架,并层层迭代地分析和完善 Prompt。

任务

问题

解决示例

从产品说明书生成一份营销产品描述

# 示例:产品说明书
fact_sheet_chair = """
概述

    美丽的中世纪风格办公家具系列的一部分,包括文件柜、办公桌、书柜、会议桌等。
    多种外壳颜色和底座涂层可选。
    可选塑料前后靠背装饰(SWC-100)或10种面料和6种皮革的全面装饰(SWC-110)。
    底座涂层选项为:不锈钢、哑光黑色、光泽白色或铬。
    椅子可带或不带扶手。
    适用于家庭或商业场所。
    符合合同使用资格。

结构

    五个轮子的塑料涂层铝底座。
    气动椅子调节,方便升降。

尺寸

    宽度53厘米|20.87英寸
    深度51厘米|20.08英寸
    高度80厘米|31.50英寸
    座椅高度44厘米|17.32英寸
    座椅深度41厘米|16.14英寸

选项

    软地板或硬地板滚轮选项。
    两种座椅泡沫密度可选:中等(1.8磅/立方英尺)或高(2.8磅/立方英尺)。
    无扶手或8个位置PU扶手。

材料
外壳底座滑动件

    改性尼龙PA6/PA66涂层的铸铝。
    外壳厚度:10毫米。
    座椅
    HD36泡沫

原产国

    意大利
"""

#   Prompt :基于说明书创建营销描述
prompt = f"""
您的任务是帮助营销团队基于技术说明书创建一个产品的营销描述。

根据```标记的技术说明书中提供的信息,编写一个产品描述。

技术说明: ```{fact_sheet_chair}```
"""
response = get_completion(prompt)
print(response)

image-20240717110122-mtv92ki.png

生成文本太长

# 优化后的 Prompt,要求生成描述不多于 50 词
prompt = f"""
您的任务是帮助营销团队基于技术说明书创建一个产品的零售网站描述。

根据```标记的技术说明书中提供的信息,编写一个产品描述。

使用最多50个词。

技术规格:```{fact_sheet_chair}```
"""
response = get_completion(prompt)
print(response)

image-20240717104418-gfvutso.png

LLM 使用分词器解释文本,字数控制不会很精确,有很多不同的方法来尝试控制您得到的输出的长度(如若干句话/词/个汉字/个字母等)。

抓错文本细节

增加面向零售商对象:

# 优化后的 Prompt,说明面向对象,应具有什么性质且侧重于什么方面
prompt = f"""
您的任务是帮助营销团队基于技术说明书创建一个产品的零售网站描述。

根据```标记的技术说明书中提供的信息,编写一个产品描述。

该描述面向家具零售商,因此应具有技术性质,并侧重于产品的材料构造。

使用最多50个单词。

技术规格: ```{fact_sheet_chair}```
"""
response = get_completion(prompt)
print(response)

image-20240717104424-2fqnmna.png

增加产品ID:

# 更进一步
prompt = f"""
您的任务是帮助营销团队基于技术说明书创建一个产品的零售网站描述。

根据```标记的技术说明书中提供的信息,编写一个产品描述。

该描述面向家具零售商,因此应具有技术性质,并侧重于产品的材料构造。

在描述末尾,包括技术规格中每个7个字符的产品ID。

使用最多50个单词。

技术规格: ```{fact_sheet_chair}```
"""
response = get_completion(prompt)
print(response)

image-20240717104431-dgxdpql.png

添加表格描述

# 要求它抽取信息并组织成表格,并指定表格的列、表名和格式
from IPython.display import display, HTML
prompt = f"""
您的任务是帮助营销团队基于技术说明书创建一个产品的零售网站描述。

根据```标记的技术说明书中提供的信息,编写一个产品描述。

该描述面向家具零售商,因此应具有技术性质,并侧重于产品的材料构造。

在描述末尾,包括技术规格中每个7个字符的产品ID。

在描述之后,包括一个表格,提供产品的尺寸。表格应该有两列。第一列包括尺寸的名称。第二列只包括英寸的测量值。

给表格命名为“产品尺寸”。

将所有内容格式化为可用于网站的HTML格式。将描述放在<div>元素中。

技术规格:```{fact_sheet_chair}```
"""

response = get_completion(prompt)
print(response)
display(HTML(response))

image-20240717110554-xakw3kw.png

3.3.3 文本概括

单一文本

以商品评论的总结任务为例:对于电商平台来说,网站上往往存在着海量的商品评论,这些评论反映了所有客户的想法。如果我们拥有一个工具去概括这些海量、冗长的评论,便能够快速地浏览更多评论,洞悉客户的偏好,从而指导平台与商家提供更优质的服务。

prod_review_zh = """
这个熊猫公仔是我给女儿的生日礼物,她很喜欢,去哪都带着。
公仔很软,超级可爱,面部表情也很和善。但是相比于价钱来说有点小贵,
它有点小,我感觉在别的地方用同样的价钱能买到更大的。
快递比预期提前了一天到货,所以在送给女儿之前,我自己玩了会。
"""

迭代

示例结果

限制输出长度

prompt = f"""
您的任务是从电子商务网站上生成一个产品评论的简短摘要。

请对三个反引号之间的评论文本进行概括,最多30个词汇。

评论: ```{prod_review_zh}```
"""

response = get_completion(prompt)
print(response)


image-20240717104448-c7rf4c5.png

设置关键角度侧重

侧重于快递服务

prompt = f"""
您的任务是从电子商务网站上生成一个产品评论的简短摘要。

请对三个反引号之间的评论文本进行概括,最多30个词汇,并且聚焦在产品运输上。

评论: ```{prod_review_zh}```
"""

response = get_completion(prompt)
print(response)

image-20240717104458-gifkpx7.png

侧重于价格和质量

prompt = f"""
您的任务是从电子商务网站上生成一个产品评论的简短摘要。

请对三个反引号之间的评论文本进行概括,最多30个词汇,并且聚焦在产品价格和质量上。

评论: ```{prod_review_zh}```
"""

response = get_completion(prompt)
print(response)

image-20240717104506-cd1c9zw.png

关键信息提取

只提取某一角度的信息,要求 LLM 进行“文本提取”而非“概括 ”

prompt = f"""
您的任务是从电子商务网站上的产品评论中提取相关信息。

请从以下三个反引号之间的评论文本中提取产品运输相关的信息,最多30个词汇。

评论: ```{prod_review_zh}```
"""

response = get_completion(prompt)
print(response)

image-20240717104511-rzc401q.png

多条文本

review_1 = prod_review

# review for a standing lamp
review_2 = """
我想为我的卧室找一个漂亮的灯,这款灯还有额外的存储空间,价格也不太高。\
购买后很快就收到了,两天就送到了。但在运输过程中,灯的拉链断了,公司态度\
很好,发来了一条新的。新的拉链也在几天内就到了。这个灯非常容易装配。后来,我\
发现缺少一个部分,所以我联系了他们的客户支持,他们很快就给我寄来了缺失的部件\
!我觉得这是一家非常关心他们的客户和产品的好公司。
"""

# review for an electric toothbrush
review_3 = """
我的牙科卫生师推荐我使用电动牙刷,这就是我购买这款牙刷的原因。目前为止,我发现电池的\
续航时间颇为令人印象深刻。在初次充电并在第一周保持充电器插头插入以调节电池状态之后,我\
已经将充电器拔掉,并在过去的3周里,每天两次刷牙都使用同一次充电。然而,这款牙刷的刷头实\
在太小了。我见过的婴儿牙刷都比这个大。我希望牙刷头能做得更大一些,搭配不同长度的刷毛更好\
地清洁牙齿间缝,因为现有的无法做到这一点。总的来说,如果你能以大约50美元的价格购入这款电动\
牙刷,那它就物超所值。厂家配套的替换刷头价格相当昂贵,但你可以买到价格更为合理的通用款。\
使用这款牙刷让我感觉像每天都去看了牙医一样,我的牙齿感觉洁净如新!
"""

# review for a blender
review_4 = """
他们还在11月把17件套系统以大约$49的优惠价格销售,几乎是五折。但不明原因(轻易就可以归咎为价格欺诈)\
在到了12月第二周,同一套系统的价格一下儿飙升到了$70-$89之间。11件套系统的价格也从之前的优惠价$29上\
升了大概$10。看上去还算公道,但如果你仔细观察底部,会发现刀片锁定的部位相比几年前的版本要略逊一筹,所\
以我打算非常小心翼翼地使用(例如,我会将像豆子、冰块、大米之类的硬质食材先用搅拌机压碎,然后调到我需要\
的份量,再用打发刀片研磨成更细的粉状,制作冰沙时我首选交叉刀片,如果需要更细腻些或者少些浆糊状,我会换成\
平刀)。在制作果昔时,把将要用的水果和蔬菜切片冷冻是个小技巧(如果你打算用菠菜,要先稍微焖炖软,再冷冻,\
制作雪葩时,用一个小到中号的食品加工器就行)这样就不用或者很少加冰块到你的果昔了。大约一年后,电机开始发出\
一些可疑的声音。我联系了客服,但保修期已经过期,所以我只好另购一台。友情提示:这类产品的整体质量都在下滑,\
所以他们更多的是利用品牌知名度和消费者的忠诚度来保持销售。我在两天之后就收到了它。
"""

reviews = [review_1, review_2, review_3, review_4]

迭代

示例效果

for 循环多条文本概括

for i in range(len(reviews)):
    prompt = f"""
    你的任务是从电子商务网站上的产品评论中提取相关信息。

    请对三个反引号之间的评论文本进行概括,最多20个词汇。

    评论文本: ```{reviews[i]}```
    """
    response = get_completion(prompt)
    print(i, response, "\n")

image-20240717104518-wjzpbv4.png

3.3.4 推断

利用 LLM 提取标签、提取实体、理解文本情感等等。从一段文本中提取正面或负面情感,在传统的机器学习工作流程中,需要收集标签数据集、训练模型、确定如何在云端部署模型并进行推断。执行全流程需要很多工作,对于每个任务,如情感分析、提取实体等,都需要训练和部署单独的模型。通过 LLM 只需要编写一个 Prompt 就可以,不需要知道训练和部署的细节。

lamp_review_zh = """
我需要一盏漂亮的卧室灯,这款灯具有额外的储物功能,价格也不算太高。\
我很快就收到了它。在运输过程中,我们的灯绳断了,但是公司很乐意寄送了一个新的。\
几天后就收到了。这款灯很容易组装。我发现少了一个零件,于是联系了他们的客服,他们很快就给我寄来了缺失的零件!\
在我看来,Lumina 是一家非常关心顾客和产品的优秀公司!
"""

情感推理与信息提取

以电商平台关于一盏台灯的评论为例,可以对其传达的情感进行二分类(正向/负向)。

场景

示例结果

情感分类

判断情感

# 中文
prompt = f"""
以下用三个反引号分隔的产品评论的情感是什么?

评论文本: ```{lamp_review_zh}```
"""
response = get_completion(prompt)
print(response)

image-20240717104525-gbp2snq.png

简介回答

prompt = f"""
以下用三个反引号分隔的产品评论的情感是什么?

用一个单词回答:「正面」或「负面」。

评论文本: ```{lamp_review_zh}```
"""
response = get_completion(prompt)
print(response)

image-20240717104532-vmsklcq.png

识别情感类型

# 中文
prompt = f"""
识别以下评论的作者表达的情感。包含不超过五个项目。将答案格式化为以逗号分隔的单词列表。

评论文本: ```{lamp_review_zh}```
"""
response = get_completion(prompt)
print(response)

image-20240717104545-g9dh5br.png

识别愤怒

prompt = f"""
以下评论的作者是否表达了愤怒?评论用三个反引号分隔。给出是或否的答案。

评论文本: ```{lamp_review_zh}```
"""
response = get_completion(prompt)
print(response)

image-20240717104553-1xf0cqr.png

商品信息提取

# 中文
prompt = f"""
从评论文本中识别以下项目:
- 评论者购买的物品
- 制造该物品的公司

评论文本用三个反引号分隔。将你的响应格式化为以 “物品” 和 “品牌” 为键的 JSON 对象。
如果信息不存在,请使用 “未知” 作为值。
让你的回应尽可能简短。
  
评论文本: ```{lamp_review_zh}```
"""
response = get_completion(prompt)
print(response)

image-20240717104559-oy32h0h.png

助于追踪特定物品或制造商收获的用户情感趋势。

综合完成任务

# 中文
prompt = f"""
从评论文本中识别以下项目:
- 情绪(正面或负面)
- 审稿人是否表达了愤怒?(是或否)
- 评论者购买的物品
- 制造该物品的公司

评论用三个反引号分隔。将您的响应格式化为 JSON 对象,以 “Sentiment”、“Anger”、“Item” 和 “Brand” 作为键。
如果信息不存在,请使用 “未知” 作为值。
让你的回应尽可能简短。
将 Anger 值格式化为布尔值。

评论文本: ```{lamp_review_zh}```
"""
response = get_completion(prompt)
print(response)

image-20240717104610-jl6r9p3.png

主题推理

story_zh = """
在政府最近进行的一项调查中,要求公共部门的员工对他们所在部门的满意度进行评分。
调查结果显示,NASA 是最受欢迎的部门,满意度为 95%。

一位 NASA 员工 John Smith 对这一发现发表了评论,他表示:
“我对 NASA 排名第一并不感到惊讶。这是一个与了不起的人们和令人难以置信的机会共事的好地方。我为成为这样一个创新组织的一员感到自豪。”

NASA 的管理团队也对这一结果表示欢迎,主管 Tom Johnson 表示:
“我们很高兴听到我们的员工对 NASA 的工作感到满意。
我们拥有一支才华横溢、忠诚敬业的团队,他们为实现我们的目标不懈努力,看到他们的辛勤工作得到回报是太棒了。”

调查还显示,社会保障管理局的满意度最低,只有 45%的员工表示他们对工作满意。
政府承诺解决调查中员工提出的问题,并努力提高所有部门的工作满意度。
"""
prompt = f"""
确定以下给定文本中讨论的五个主题。

每个主题用1-2个单词概括。

输出时用逗号分割每个主题。

给定文本: ```{story_zh}```
"""
response = get_completion(prompt)
print(response)

image-20240717104615-lzw54nz.png

为特定主题制作新闻提醒

prompt = f"""
判断主题列表中的每一项是否是给定文本中的一个话题,

以列表的形式给出答案,每个主题用 0 或 1。

主题列表:美国航空航天局、当地政府、工程、员工满意度、联邦政府

给定文本: ```{story_zh}```
"""
response = get_completion(prompt)
print(response)

image-20240717111703-85s1fo9.png

机器学习中有时称为 零样本学习算法,因为我们没有给它任何标记的训练数据。

3.3.5 文本转换

文本翻译

场景

中文转西班牙语

prompt = f"""
将以下中文翻译成西班牙语: \ 
```您好,我想订购一个搅拌机。```
"""
response = get_completion(prompt)
print(response)

image-20240717104625-jbaq123.png

识别语种

prompt = f"""
请告诉我以下文本是什么语种: 
```Combien coûte le lampadaire?```
"""
response = get_completion(prompt)
print(response)

image-20240717104632-p3qnhxf.png

多语种翻译

prompt = f"""
请将以下文本分别翻译成中文、英文、法语和西班牙语: 
```I want to order a basketball.```
"""
response = get_completion(prompt)
print(response)

image-20240717104638-cr7o3j8.png

同时进行语气转换

prompt = f"""
请将以下文本翻译成中文,分别展示成正式与非正式两种语气: 
```Would you like to order a pillow?```
"""
response = get_completion(prompt)
print(response)

image-20240717104642-ul89w1o.png

通用翻译器

user_messages = [
  "La performance du système est plus lente que d'habitude.",  # System performance is slower than normal         
  "Mi monitor tiene píxeles que no se iluminan.",              # My monitor has pixels that are not lighting
  "Il mio mouse non funziona",                                 # My mouse is not working
  "Mój klawisz Ctrl jest zepsuty",                             # My keyboard has a broken control key
  "我的屏幕在闪烁"                                             # My screen is flashing
]
import time
for issue in user_messages:
    time.sleep(20)
    prompt = f"告诉我以下文本是什么语种,直接输出语种,如法语,无需输出标点符号: ```{issue}```"
    lang = get_completion(prompt)
    print(f"原始消息 ({lang}): {issue}\n")

    prompt = f"""
    将以下消息分别翻译成英文和中文,并写成
    中文翻译:xxx
    英文翻译:yyy
    的格式:
    ```{issue}```
    """
    response = get_completion(prompt)
    print(response, "\n=========================================")

image-20240717104651-u4f3luc.png

语气与写作风格调整

prompt = f"""
将以下文本翻译成商务信函的格式: 
```小老弟,我小羊,上回你说咱部门要采购的显示器是多少寸来着?```
"""
response = get_completion(prompt)
print(response)

image-20240717104708-zihou1j.png

文件格式转换

data_json = { "resturant employees" :[ 
    {"name":"Shyam", "email":"shyamjaiswal@gmail.com"},
    {"name":"Bob", "email":"bob32@gmail.com"},
    {"name":"Jai", "email":"jai87@gmail.com"}
]}
from IPython.display import display, Markdown, Latex, HTML, JSON
prompt = f"""
将以下内容从JSON转换为HTML表格直接输出,保留表格标题和列名:{data_json}
"""
response = get_completion(prompt)
print(response)
display(HTML(response))

image-20240717104716-musac47.png

拼写及语法纠正

拼写及语法的检查与纠正是一个十分常见的需求,特别是使用非母语语言,例如,在论坛发帖时,或发表英文论文时,校对是一件十分重要的事情。

for i in range(len(text)):
    time.sleep(20)
    prompt = f"""请校对并更正以下文本,注意纠正文本保持原始语种,无需输出原始文本。
    如果您没有发现任何错误,请说“未发现错误”。
    
    例如:
    输入:I are happy.
    输出:I am happy.
    ```{text[i]}```"""
    response = get_completion(prompt)
    print(i, response)

综合样例

下述例子展示了同一段评论,用一段 Prompt 同时进行文本翻译+拼写纠正+风格调整+格式转换。

text = f"""
Got this for my daughter for her birthday cuz she keeps taking \
mine from my room.  Yes, adults also like pandas too.  She takes \
it everywhere with her, and it's super soft and cute.  One of the \
ears is a bit lower than the other, and I don't think that was \
designed to be asymmetrical. It's a bit small for what I paid for it \
though. I think there might be other options that are bigger for \
the same price.  It arrived a day earlier than expected, so I got \
to play with it myself before I gave it to my daughter.
"""
prompt = f"""
针对以下三个反引号之间的英文评论文本,
首先进行拼写及语法纠错,
然后将其转化成中文,
再将其转化成优质淘宝评论的风格,从各种角度出发,分别说明产品的优点与缺点,并进行总结。
润色一下描述,使评论更具有吸引力。
输出结果格式为:
【优点】xxx
【缺点】xxx
【总结】xxx
注意,只需填写xxx部分,并分段输出。
将结果输出成Markdown格式。
```{text}```
"""
response = get_completion(prompt)
display(Markdown(response))

image-20240717104726-ery3udq.png

3.3.6 文本扩展

扩展是将短文本输入到大型语言模型中,让模型生成更长的文本。

定制客户邮件
根据客户评价和情感,针对性写自动回复邮件。

# 我们学习到如何对一个评论判断其情感倾向
sentiment = "negative"

# 一个产品的评价
review = f"""
他们在11月份的季节性销售期间以约49美元的价格出售17件套装,折扣约为一半。\
但由于某些原因(可能是价格欺诈),到了12月第二周,同样的套装价格全都涨到了70美元到89美元不等。\
11件套装的价格也上涨了大约10美元左右。\
虽然外观看起来还可以,但基座上锁定刀片的部分看起来不如几年前的早期版本那么好。\
不过我打算非常温柔地使用它,例如,\
我会先在搅拌机中将像豆子、冰、米饭等硬物研磨,然后再制成所需的份量,\
切换到打蛋器制作更细的面粉,或者在制作冰沙时先使用交叉切割刀片,然后使用平面刀片制作更细/不粘的效果。\
制作冰沙时,特别提示:\
将水果和蔬菜切碎并冷冻(如果使用菠菜,则轻轻煮软菠菜,然后冷冻直到使用;\
如果制作果酱,则使用小到中号的食品处理器),这样可以避免在制作冰沙时添加太多冰块。\
大约一年后,电机发出奇怪的噪音,我打电话给客服,但保修已经过期了,所以我不得不再买一个。\
总的来说,这些产品的总体质量已经下降,因此它们依靠品牌认可和消费者忠诚度来维持销售。\
货物在两天内到达。
"""
prompt = f"""
你是一位客户服务的AI助手。
你的任务是给一位重要客户发送邮件回复。
根据客户通过“```”分隔的评价,生成回复以感谢客户的评价。提醒模型使用评价中的具体细节
用简明而专业的语气写信。
作为“AI客户代理”签署电子邮件。
客户评论:
```{review}```
评论情感:{sentiment}
"""
response = get_completion(prompt)
print(response)

image-20240717104758-l0smnfh.png

引入温度系数
利用模型的另一个输入参数称为温度,这种参数使得模型响应多样性。如果构建一个可靠和可预测的系统,可以设置温度为0,如果需要更具创意,可以输入使用更高的温度。

prompt = f"""
你是一名客户服务的AI助手。
你的任务是给一位重要的客户发送邮件回复。
根据通过“```”分隔的客户电子邮件生成回复,以感谢客户的评价。
如果情感是积极的或中性的,感谢他们的评价。
如果情感是消极的,道歉并建议他们联系客户服务。
请确保使用评论中的具体细节。
以简明和专业的语气写信。
以“AI客户代理”的名义签署电子邮件。
客户评价:```{review}```
评论情感:{sentiment}
"""
response = get_completion(prompt, temperature=0.7)
print(response)

image-20240717104818-o88zfu9.png

所以,再次执行将再次获得不同的电子邮件,在更高的温度下,模型的输出更加随机,更具创造力。

3.3.7 聊天机器人

可以利用 api 参数 assistant 角色生成聊天机器人,用于点餐机器人、产品咨询 IM 等。

四、如何微调训练私有大模型

4.1 训练步骤

步骤通常可以分为①数据准备(数据收集、数据清洗、 数据增强)、②模型选择和训练(模型架构、预训练模型、训练代码、超参优化、)、③评估和优化(评估 指标、交叉验证、错误分析)、④部署和维护等几个阶段。

4.2 微调一个预训练模型

下面通过一个简单的情感分类任务,展示如何使用 GPT 模型进行文本分类,适用场景:

  • 社交媒体、客户反馈等文本数据中进行情感分类;

  • 垃圾邮件检测、主题分类;

  • 复任务例如对话系统、文本摘要等

# PyTorch库,用于深度学习模型。
import torch  
# Hugging Face Transformers库中的模块,用于加载GPT-2模型和分词器。Trainer 和 TrainingArguments:用于简化模型训练和评估的工具。
from transformers import GPT2Tokenizer, GPT2ForSequenceClassification, Trainer, TrainingArguments 
# 用于加载数据集和评估指标。
from datasets import load_dataset, load_metric
# 操作系统模块,用于路径操作。
import os

# 使用 token 参数加载模型
#model = AutoModelForCausalLM.from_pretrained("your-username/your-model-name", token="your_huggingface_token")
#tokenizer = AutoTokenizer.from_pretrained("your-username/your-model-name", token="your_huggingface_token")


# 1、加载数据集 使用Hugging Face Datasets库加载CSV格式的训练数据,从一个 CSV 文件中加载文本数据和标签。每个示例包含一段文本和一个情感标签(正面或负面)。
dataset = load_dataset('csv', data_files='train_en.csv')

# 2、加载预训练模型和分词器,使用 Hugging Face 的 Transformers 库加载预训练的 distilgpt2 模型和对应的分词器。
model_name = "distilgpt2" # 7千万参数 我们使用 distilgpt2 模型来进行微调
tokenizer = GPT2Tokenizer.from_pretrained(model_name) # 加载预训练的GPT-2分词器
model = GPT2ForSequenceClassification.from_pretrained(model_name, num_labels=2) # 加载预训练的GPT-2模型,并指定输出为2类(例如,正面和负面)。

# 添加填充标记,设置填充标记为模型的结束标记,因为GPT-2默认没有定义填充标记。
tokenizer.pad_token = tokenizer.eos_token
model.config.pad_token_id = tokenizer.eos_token_id


# 3、数据预处理函数,使用分词器将文本数据转换为模型可以理解的输入格式,包括添加填充标记以确保输入序列长度一致。
# 该函数将输入文本转换为模型所需的格式
def preprocess_function(examples):
    label_map = {"positive": 1, "negative": 0} # 将文本标签转换为数值
    examples["label"] = [label_map[label.strip().strip('"')] for label in examples["label"]]
    return tokenizer(examples['text'], padding="max_length", truncation=True) # 将文本转换为模型所需的输入格式,添加填充和截断。

# 对数据集进行预处理,使用 map 方法对数据集进行批量预处理。
tokenized_datasets = dataset.map(preprocess_function, batched=True)

# 4、训练参数配置,定义训练参数,例如学习率、批量大小、训练轮数等。
training_args = TrainingArguments(
    output_dir="./results",               # 训练结果输出目录,在训练过程中,模型的检查点(checkpoints)和最终模型会保存到这个目录中。
    evaluation_strategy="epoch",          # 每个epoch进行一次评估,可以设置为 "no"(不进行评估)、"steps"(每隔一定步数进行评估)或 "epoch"(每个epoch结束后进行评估)
    learning_rate=2e-5,                   # 学习率,控制模型参数更新的步伐。学习率过高可能导致训练不稳定,过低可能导致收敛速度慢。通常需要调整以找到最佳值。
    per_device_train_batch_size=1,        # 每个设备的训练batch大小,批量大小超过1时,GPT-2无法处理;指定每个GPU/TPU/CPU在训练时处理的样本数量。批量大小的选择会影响训练速度和内存使用。
    per_device_eval_batch_size=2,         # 每个设备的评估batch大小,指定每个GPU/TPU/CPU在评估时处理的样本数量。通常评估批量大小可以设置得比训练批量大小大。
    num_train_epochs=10,                   # 训练的总epoch数,一个epoch表示模型已经完整地遍历了一遍训练数据。设置训练的总epoch数可以控制训练的总轮次。
    weight_decay=0.01,                    # 权重衰减(L2正则化),在每次参数更新时对模型的权重进行衰减,可以防止过拟合。通常需要调试以找到最佳值。
)


# 5、定义评估指标,这里我们使用准确率作为评估指标,使用本地 accuracy.py 文件,衡量模型在验证集上的表现。
metric_path = os.path.join(os.path.dirname(__file__), "metrics/accuracy.py")
metric = load_metric(metric_path)

# 计算评估指标
def compute_metrics(eval_pred):
    logits, labels = eval_pred
     # 转换为 PyTorch 张量
    logits = torch.tensor(logits)
    labels = torch.tensor(labels)
    predictions = torch.argmax(logits, dim=-1)
    return metric.compute(predictions=predictions, references=labels) # 计算预测结果的准确率。

# 6、创建Trainer实例,使用 Hugging Face 的 Trainer 类简化训练和评估过程。
# Trainer类用于简化训练和评估过程
trainer = Trainer(
    model=model,                          # 要微调的模型
    args=training_args,                   # 训练参数
    train_dataset=tokenized_datasets["train"],  # 训练数据集
    eval_dataset=tokenized_datasets["train"],   # 评估数据集
    compute_metrics=compute_metrics,      # 评估指标
)

# 7、开始训练模型,在训练数据集上微调预训练的 GPT 模型。
trainer.train()

# 评估模型,在验证数据集上评估模型的性能,输出准确率。
# 训练完成后,对模型进行评估并打印结果
results = trainer.evaluate()
print(f"Accuracy: {results['eval_accuracy']}")


# 保存模型和分词器
model.save_pretrained("./V3distilgpt2_saved_model")
tokenizer.save_pretrained("./V3distilgpt2_saved_model")

4.3 案例演示

模型

训练数据集

超参数(学习率、批量大小、训练轮数)

模型训练结果

测试效果

distilgpt2

text,label
"I love programming in Python!", "positive"
"Debugging code is frustrating.", "negative"
"Machine learning is fascinating.", "positive"
"I hate syntax errors.", "negative"
"Natural Language Processing is amazing!", "positive"

# 训练参数配置
training_args = TrainingArguments(
    output_dir="./results",               # 训练结果输出目录
    evaluation_strategy="epoch",          # 每个epoch进行一次评估
    learning_rate=2e-5,                   # 学习率
    per_device_train_batch_size=1,        # 每个设备的训练batch大小,批量大小超过1时,GPT-2无法处理
    per_device_eval_batch_size=1,         # 每个设备的评估batch大小
    num_train_epochs=3,                   # 训练的总epoch数
    weight_decay=0.01,                    # 权重衰减
)

准确率评分:60%

image-20240717112422-xxspbgs.png

正确率:60%
image-20240717112428-1wuuxf6.png

distilgpt2

text,label
"I love programming in Python!", "positive"
"Debugging code is frustrating.", "negative"
"Machine learning is fascinating.", "positive"
"I hate syntax errors.", "negative"
"Natural Language Processing is amazing!", "positive"
"The user interface is very intuitive.", "positive"
"Customer service was very helpful.", "positive"
"The new update is full of bugs.", "negative"
"Waiting for the application to load is annoying.", "negative"
"The performance of the system is impressive.", "positive"
"The error messages are very confusing.", "negative"
"The documentation is very comprehensive.", "positive"
"Connecting to the server always takes too long.", "negative"
"The graphics are stunning and very detailed.", "positive"
"I can't get any support from the team.", "negative"
"The features are exactly what I needed.", "positive"
"The setup process was a bit complicated.", "negative"
"The quality of the product exceeded my expectations.", "positive"
"The application crashes frequently.", "negative"
"The installation was quick and easy.", "positive"
"The battery life of this device is too short.", "negative"
"I appreciate the regular updates and improvements.", "positive"
"The software is very user-friendly.", "positive"
"I had a terrible experience with the customer service.", "negative"
"The speed of the internet connection is excellent.", "positive"
"The design is sleek and modern.", "positive"
"I always encounter errors when trying to use this feature.", "negative"
"The product arrived on time and in perfect condition.", "positive"
"The customer support was not helpful at all.", "negative"
"The instructions were clear and easy to follow.", "positive"
"The device overheats quickly.", "negative"
"The packaging was really nice and secure.", "positive"
"The app is very slow and unresponsive.", "negative"

准确率评分:81%
image-20240717112531-k7hk285.png

正确率:80%
image-20240717112605-c9v7zcs.png

distilgpt2

​增加每个设备的评估batch大小,1->2

# 训练参数配置
training_args = TrainingArguments(
    output_dir="./results",               # 训练结果输出目录,在训练过程中,模型的检查点(checkpoints)和最终模型会保存到这个目录中。
    evaluation_strategy="epoch",          # 每个epoch进行一次评估,可以设置为 "no"(不进行评估)、"steps"(每隔一定步数进行评估)或 "epoch"(每个epoch结束后进行评估)
    learning_rate=2e-5,                   # 学习率,控制模型参数更新的步伐。学习率过高可能导致训练不稳定,过低可能导致收敛速度慢。通常需要调整以找到最佳值。
    per_device_train_batch_size=1,        # 每个设备的训练batch大小,批量大小超过1时,GPT-2无法处理;指定每个GPU/TPU/CPU在训练时处理的样本数量。批量大小的选择会影响训练速度和内存使用。
    per_device_eval_batch_size=2,         # 每个设备的评估batch大小,指定每个GPU/TPU/CPU在评估时处理的样本数量。通常评估批量大小可以设置得比训练批量大小大。
    num_train_epochs=5,                   # 训练的总epoch数,一个epoch表示模型已经完整地遍历了一遍训练数据。设置训练的总epoch数可以控制训练的总轮次。
    weight_decay=0.01,                    # 权重衰减(L2正则化),在每次参数更新时对模型的权重进行衰减,可以防止过拟合。通常需要调试以找到最佳值。
)

准确率:96%
image-20240717112745-1c6k8ck.png

正确率:100%
image-20240717112813-bapa1jy.png

distilgpt2

增加训练的总epoch数,5->10

# 训练参数配置
training_args = TrainingArguments(
    output_dir="./results",               # 训练结果输出目录,在训练过程中,模型的检查点(checkpoints)和最终模型会保存到这个目录中。
    evaluation_strategy="epoch",          # 每个epoch进行一次评估,可以设置为 "no"(不进行评估)、"steps"(每隔一定步数进行评估)或 "epoch"(每个epoch结束后进行评估)
    learning_rate=2e-5,                   # 学习率,控制模型参数更新的步伐。学习率过高可能导致训练不稳定,过低可能导致收敛速度慢。通常需要调整以找到最佳值。
    per_device_train_batch_size=1,        # 每个设备的训练batch大小,批量大小超过1时,GPT-2无法处理;指定每个GPU/TPU/CPU在训练时处理的样本数量。批量大小的选择会影响训练速度和内存使用。
    per_device_eval_batch_size=2,         # 每个设备的评估batch大小,指定每个GPU/TPU/CPU在评估时处理的样本数量。通常评估批量大小可以设置得比训练批量大小大。
    num_train_epochs=10,                   # 训练的总epoch数,一个epoch表示模型已经完整地遍历了一遍训练数据。设置训练的总epoch数可以控制训练的总轮次。
    weight_decay=0.01,                    # 权重衰减(L2正则化),在每次参数更新时对模型的权重进行衰减,可以防止过拟合。通常需要调试以找到最佳值。
)

准确率:100%
image-20240717112851-1nzf131.png

正确率:100%
image-20240717112900-j6l14c1.png

distilgpt2

text,label
"我喜欢用Python编程!", "positive"
"调试代码真让人沮丧。", "negative"
"机器学习很有趣。", "positive"
"我讨厌语法错误。", "negative"
"自然语言处理太棒了!", "positive"
"用户界面非常直观。", "positive"
"客服非常有帮助。", "positive"
"新更新充满了bug。", "negative"
"等待应用加载很烦人。", "negative"
"系统的性能令人印象深刻。", "positive"
"错误信息非常令人困惑。", "negative"
"文档非常详尽。", "positive"
"连接到服务器总是很慢。", "negative"
"图形非常华丽且详细。", "positive"
"我无法从团队得到任何支持。", "negative"
"这些功能正是我需要的。", "positive"
"设置过程有点复杂。", "negative"
"产品质量超出了我的预期。", "positive"
"应用程序经常崩溃。", "negative"
"安装过程快速且简单。", "positive"
"这个设备的电池寿命太短了。", "negative"
"我很感激定期的更新和改进。", "positive"
"软件非常用户友好。", "positive"
"我对客户服务的体验非常糟糕。", "negative"
"网络连接速度非常快。", "positive"
"设计简洁而现代。", "positive"
"每次使用这个功能时总会遇到错误。", "negative"
"产品按时到达且状态完好。", "positive"
"客户支持完全没有帮助。", "negative"
"说明书清晰易懂。", "positive"
"设备很快就会过热。", "negative"
"包装非常好且安全。", "positive"
"应用程序非常慢且无响应。", "negative"

准确率评分:51%

distilgpt2 模型对中文数据效果不佳
image-20240717112945-ktozvxl.png

bert-base-chinese

# 训练参数配置
training_args = TrainingArguments(
    output_dir="./results",               # 训练结果输出目录
    evaluation_strategy="epoch",          # 每个epoch进行一次评估
    learning_rate=2e-5,                   # 学习率
    per_device_train_batch_size=4,        # 每个设备的训练batch大小
    per_device_eval_batch_size=4,         # 每个设备的评估batch大小
    num_train_epochs=3,                   # 训练的总epoch数
    weight_decay=0.01,                    # 权重衰减
)

第一次设置批次参数8,出现内存分配不足报错
image-20240717113119-q9zbvt8.png

第二次减少批次大小,8->4,模型训练后准确率100%

image-20240717113141-sgozcc9.png

正确率:100%
image-20240717113133-ej5qt18.png

4.4 进一步的步骤

1. 改进模型:

- 尝试增加训练数据的数量和多样性,以提高模型的准确率。

- 调整模型的超参数,例如学习率、批量大小、训练轮数等。

2. 验证和测试:

- 除了准确率,还可以使用其他评估指标(例如精确率、召回率、F1分数)来全面评估模型的性能。

- 使用独立的验证集和测试集来评估模型,以确保模型的泛化能力。

3. 错误分析:

- 分析模型的错误预测,找出常见的错误类型和模式,并针对性地改进模型。