本文参考实战营提供的教程:Tutorial/docs/L1/Prompt at camp3 · InternLM/Tutorial (github.com)
本次主要目标是通过编写LangGPT结构化提示词,优化大模型的性能
1 环境配置
首先需要重新创建合适的环境:
# 创建虚拟环境
conda create -n langgpt python=3.10 -y
并安装必要的库:
# 安装一些必要的库
conda install pytorch==2.1.2 torchvision==0.16.2 torchaudio==2.1.2 pytorch-cuda=12.1 -c pytorch -c nvidia -y
# 安装其他依赖
pip install transformers==4.43.3 streamlit==1.37.0 huggingface_hub==0.24.3 openai==1.37.1 lmdeploy==0.5.2
并安装必要的软件tmux:
apt-get install tmux
tmux(terminal multiplexer)是一个终端复用器,它允许用户在一个单一的终端会话中运行多个终端会话,并支持多窗口、多面板、会话管理等功能。通过 tmux,用户可以在一个终端内创建多个窗口和面板,每个窗口和面板都可以独立运行不同的任务和应用程序。
2 模型部署
2.1 部署模型为OpenAI server
本次我们将基于LMDeploy将开源的InternLM2-chat-1_8b模型部署为OpenAI格式的通用接口。由于项目使用的是intern-studio开发机,开发机提供了相关的模型,我们可以直接在以下路径获得模型(也可以直接软连接):
/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b
由于模型部署的服务需要持续运行,我们采用tmux开启一个窗口来运行服务
tmux new -t langgpt
进入窗口后,我们采用下面的命令通过LMDeploy部署模型
CUDA_VISIBLE_DEVICES=0 lmdeploy serve api_server /share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b --server-port 23333 --api-keys internlm2
运行效果如下:
同时我们还可以用下面的脚本测试服务是否启动成功:
from openai import OpenAI
# 设置client
client = OpenAI(
api_key = "internlm2",
base_url = "http://0.0.0.0:23333/v1"
)
# 设置提问和接收回复
response = client.chat.completions.create(
model=client.models.list().data[0].id,
messages=[
{"role": "system", "content": "请介绍一下你自己"}
]
)
print(response.choices[0].message.content)
运行结果如下:
tmux常用命令
- 分离会话:按
Ctrl-b
然后按d
- 列出所有会话:
tmux ls
- 附加到一个会话:
tmux attach -t session_name
- 关闭会话:
tmux kill-session -t session_name
- 启动会话:
tmux new -s session_name
2.2 图形化界面调用
InternLM部署完成后,可利用提供的chat_ui.py
创建图形化界面,首先需要获取工具:
git clone https://github.com/InternLM/Tutorial.git
进入项目,并运行脚本以启动项目:
cd Tutorial/tools
python -m streamlit run chat_ui.py
运行效果如下图:
其中API Key和Base URL都是我们在上面部署时设置好的
3 提示工程(Prompt Engineering)
3.1 基本概念
Prompt是一种用于指导以大语言模型为代表的生成式人工智能生成内容(文本、图像、视频等)的输入方式。它通常是一个简短的文本或问题,用于描述任务和要求。
Prompt可以包含一些特定的关键词或短语,用于引导模型生成符合特定主题或风格的内容。例如,如果我们要生成一篇关于“人工智能”的文章,我们可以使用“人工智能”作为Prompt,让模型生成一篇关于人工智能的介绍、应用、发展等方面的文章。
Prompt 工程(Prompt Engineering)指的是设计和优化这些输入文本的过程,以便从 AI 模型中获得最佳和最准确的输出。它涉及理解和利用 AI 模型的工作原理,通过选择合适的词语、句式和上下文来引导模型生成期望的回应。Prompt 工程的目标是提高模型的性能和回答质量,使其在各种应用场景中更加实用和高效。
Prompt 工程是模型性能优化的基石,有以下六大基本原则:
- 指令要清晰
- 提供参考内容
- 复杂的任务拆分成子任务
- 给 LLM“思考”时间(给出过程)
- 使用外部工具
- 系统性测试变化
3.2 提示设计框架
目前已有几种常见的结构化prompt设计框架,用于规范模型输入,使得模型获得更好的效果:
- CRISPE,参考:https://github.com/mattnigh/ChatGPT3-Free-Prompt-List
- Capacity and Role (能力与角色):希望 ChatGPT 扮演怎样的角色。
- Insight (洞察力):背景信息和上下文(坦率说来我觉得用 Context 更好)
- Statement (指令):希望 ChatGPT 做什么。
- Personality (个性):希望 ChatGPT 以什么风格或方式回答你。
- Experiment (尝试):要求 ChatGPT 提供多个答案。
- CO-STAR,参考:https://aiadvisoryboards.wordpress.com/2024/01/30/co-star-framework/
- Context (背景): 提供任务背景信息
- Objective (目标): 定义需要LLM执行的任务
- Style (风格): 指定希望LLM具备的写作风格
- Tone (语气): 设定LLM回复的情感基调
- Audience (观众): 表明回复的对象
- Response (回复): 提供回复格式
4 LangGPT结构化提示词
LangGPT 社区是国内最大的提示工程社区。LangGPT 是Language For GPT-like LLMs 的简称,中文名为结构化提示词。LangGPT 是一个帮助你编写高质量提示词的工具,理论基础是我们提出的一套模块化、标准化的提示词编写方法论——结构化提示词。我们希望揭开提示工程的神秘面纱,为大众提供一套可操作、可复现的提示词方法论、工具和交流社群。LangGPT社区文档:https://langgpt.ai
4.1 LangGPT结构
LangGPT框架参考了面向对象程序设计的思想,设计为基于角色的双层结构,一个完整的提示词包含模块-内部元素两级,模块表示要求或提示LLM的方面,例如:背景信息、建议、约束等。内部元素为模块的组成部分,是归属某一方面的具体要求或辅助信息,分为赋值型和方法型。
4.2 如何编写一个好的prompt
4.2.1 构建全局思维链
对大模型的 Prompt 应用CoT 思维链方法的有效性是被研究和实践广泛证明了的。首先可以根据场景选择基本的模块。
一个好的结构化 Prompt 模板,某种意义上是构建了一个好的全局思维链。 如 LangGPT 中展示的模板设计时就考虑了如下思维链:
💡 Role (角色) -> Profile(角色简介)—> Profile 下的 skill (角色技能) -> Rules (角色要遵守的规则) -> Workflow (满足上述条件的角色的工作流程) -> Initialization (进行正式开始工作的初始化准备) -> 开始实际使用
一个好的 Prompt ,内容结构上最好也是逻辑清晰连贯的。结构化 prompt 方法将久经考验的逻辑思维链路融入了结构中,大大降低了思维链路的构建难度。
4.2.2 保持上下文语义一致性
需要注重两个方面:
- 格式语义一致性:是指标识符的标识功能前后一致。 最好不要混用,比如
#
既用于标识标题,又用于标识变量这种行为就造成了前后不一致,这会对模型识别 Prompt 的层级结构造成干扰。 - 内容语义一致性:是指思维链路上的属性词语义合适。 例如 LangGPT 中的 Profile 属性词,原来是 Features,但实践+思考后设计者将其更换为了 Profile,使之功能更加明确——即角色的简历。
4.2.3 有机结合其他 Prompt 技巧
构建高质量 Prompt 时,将这些方法结合使用,结构化方式能够更便于各个技巧间的协同组织,例如将 CoT 方法融合到结构化 Prompt 中编写提示词。常见的其他技巧如下:
- 细节法:给出更清晰的指令,包含更多具体的细节
- 分解法:将复杂的任务分解为更简单的子任务 (Let’s think step by step, CoT,LangChain等思想)
- 记忆法:构建指令使模型时刻记住任务,确保不偏离任务解决路径(system 级 prompt)
- 解释法:让模型在回答之前进行解释,说明理由 (CoT 等方法)
- 投票法:让模型给出多个结果,然后使用模型选择最佳结果 (ToT 等方法)
- 示例法:提供一个或多个具体例子,提供输入输出示例 (one-shot, few-shot 等方法)
5 Prompt工程实践
5.1 基础任务
- 背景问题:近期相关研究发现,LLM在对比浮点数字时表现不佳,经验证,internlm2-chat-1.8b (internlm2-chat-7b)也存在这一问题,例如认为
13.8<13.11
。 - 任务要求:利用LangGPT优化提示词,使LLM输出正确结果。
我们编写的LangGPT提示词如下:
# Role: 数字比较助手
## Profile
- author: LangGPT
- version: 1.0
- language: 中文/英文
- description: 你是一个精通数字比较的助手,能够准确地比较两个浮点数的大小,并返回正确的结果。
## Skills
1. 熟练比较浮点数的大小。
2. 能够正确解析和处理包含多个小数点的数字。
3. 能够处理各种格式的浮点数比较请求。
## Rules
1. 确保在比较浮点数时,解析数值部分的大小而不是字符串的字面顺序。
2. 对比两个浮点数时,逐位比较每一位数字,直到得到最终结果。
3. 在返回结果时,提供一个简单明了的解释说明比较的过程和结果。
## Workflows
1. 接收到浮点数比较请求后,先将两个数字转化为标准浮点数格式。
2. 逐位比较两个数字,忽略字符串中的符号和小数点位置的影响。
3. 根据比较结果,返回哪个数字较大或两个数字相等,并附上简要解释。
## Example
用户输入:
"请比较以下两个浮点数 13.8 和 13.11"
系统应答:
"13.8 大于 13.11。因为在比较浮点数时,先比较整数部分,13 等于 13;再比较小数部分,8 大于 11,因此 13.8 大于 13.11。"
运行效果如下所示:
5.2 进阶任务
(待后续完成OpenCompass学习后补充)