首页 > 其他分享 >LangChain使用fine-tuned GPT-3.5

LangChain使用fine-tuned GPT-3.5

时间:2023-09-24 19:00:12浏览次数:52  
标签:content messages LangChain tuned tokens 3.5 role print message

LangChain使用fine-tuned GPT-3.5

参考:

https://openai.com/blog/gpt-3-5-turbo-fine-tuning-and-api-updates

https://platform.openai.com/docs/guides/fine-tuning

https://qiita.com/MandoNarin/items/6fadb78f357c66e25502

事前准备

!pip install openai
!pip install tiktoken
!pip install langchain
import os
os.environ["OPENAI_API_KEY"] = YOUR_KEY

准备数据

数据文件 mydata.jsonl

{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the capital of France?"}, {"role": "assistant", "content": "Paris, as if everyone doesn't know that already."}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who wrote 'Romeo and Juliet'?"}, {"role": "assistant", "content": "Oh, just some guy named William Shakespeare. Ever heard of him?"}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "How far is the Moon from Earth?"}, {"role": "assistant", "content": "Around 384,400 kilometers. Give or take a few, like that really matters."}]}

官方只给了三行例子,但是会报错

# has 3 example(s), but must have at least 10 examples

我姑且复制了三遍

验证数据

https://github.com/openai/openai-cookbook/blob/main/examples/Chat_finetuning_data_prep.ipynb

直接用了上述链接里的代码

import json
import tiktoken # 为了计算token消耗
import numpy as np
from collections import defaultdict

载入数据集

# data_file_path为数据文件的地址
data_path = data_file_path

# 载入数据集
with open(data_path, 'r', encoding='utf-8') as f:
    dataset = [json.loads(line) for line in f]

# 打印初始数据集信息
print("Num examples:", len(dataset))
print("First example:")
for message in dataset[0]["messages"]:
    print(message)

检查格式是否有错

# 格式错误检查
format_errors = defaultdict(int)

for ex in dataset:
    # 是否为已知类型
    if not isinstance(ex, dict):
        format_errors["data_type"] += 1
        continue

    messages = ex.get("messages", None)
    # 检查数据集中是否每一个元素都包含"messages"键值
    if not messages:
        format_errors["missing_messages_list"] += 1
        continue

    for message in messages:
        # 检查"messages"中是否包含"role"和"content"
        if "role" not in message or "content" not in message:
            format_errors["message_missing_key"] += 1

        # 检查"messages"中是否有除了"role" "content"或者"name"之外的字段
        if any(k not in ("role", "content", "name") for k in message):
            format_errors["message_unrecognized_key"] += 1

        # 检查"role"中是否有除了"system" "user"或者"assistant"之外的值
        if message.get("role", None) not in ("system", "user", "assistant"):
            format_errors["unrecognized_role"] += 1

        content = message.get("content", None)
        # 检查"content"是否为str类型
        if not content or not isinstance(content, str):
            format_errors["missing_content"] += 1

    # 检查是否缺少"assistant"提示
    if not any(message.get("role", None) == "assistant" for message in messages):
        format_errors["example_missing_assistant_message"] += 1

if format_errors:
    print("Found errors:")
    for k, v in format_errors.items():
        print(f"{k}: {v}")
else:
    print("No errors found")

token计数

encoding = tiktoken.get_encoding("cl100k_base")

# not exact!
# simplified from https://github.com/openai/openai-cookbook/blob/main/examples/How_to_count_tokens_with_tiktoken.ipynb
def num_tokens_from_messages(messages, tokens_per_message=3, tokens_per_name=1):
    num_tokens = 0
    for message in messages:
        num_tokens += tokens_per_message
        for key, value in message.items():
            num_tokens += len(encoding.encode(value))
            if key == "name":
                num_tokens += tokens_per_name
    num_tokens += 3
    return num_tokens

def num_assistant_tokens_from_messages(messages):
    num_tokens = 0
    for message in messages:
        if message["role"] == "assistant":
            num_tokens += len(encoding.encode(message["content"]))
    return num_tokens

def print_distribution(values, name):
    print(f"\n#### Distribution of {name}:")
    print(f"min / max: {min(values)}, {max(values)}")
    print(f"mean / median: {np.mean(values)}, {np.median(values)}")
    print(f"p5 / p95: {np.quantile(values, 0.1)}, {np.quantile(values, 0.9)}")
# 警告和token计数
# 警告内容:缺少角色为system和user的数据
n_missing_system = 0
n_missing_user = 0
n_messages = []
convo_lens = []
assistant_message_lens = []

for ex in dataset:
    messages = ex["messages"]
    if not any(message["role"] == "system" for message in messages):
        n_missing_system += 1
    if not any(message["role"] == "user" for message in messages):
        n_missing_user += 1
    n_messages.append(len(messages))
    convo_lens.append(num_tokens_from_messages(messages))
    assistant_message_lens.append(num_assistant_tokens_from_messages(messages))

print("Num examples missing system message:", n_missing_system)
print("Num examples missing user message:", n_missing_user)
print_distribution(n_messages, "num_messages_per_example")
print_distribution(convo_lens, "num_total_tokens_per_example")
print_distribution(assistant_message_lens, "num_assistant_tokens_per_example")
n_too_long = sum(l > 4096 for l in convo_lens)
print(f"\n{n_too_long} examples may be over the 4096 token limit, they will be truncated during fine-tuning")

价格和默认n_epochs估计

# 价格和默认n_epochs估计
MAX_TOKENS_PER_EXAMPLE = 4096

TARGET_EPOCHS = 3
MIN_TARGET_EXAMPLES = 100
MAX_TARGET_EXAMPLES = 25000
MIN_DEFAULT_EPOCHS = 1
MAX_DEFAULT_EPOCHS = 25

n_epochs = TARGET_EPOCHS
n_train_examples = len(dataset)
if n_train_examples * TARGET_EPOCHS < MIN_TARGET_EXAMPLES:
    n_epochs = min(MAX_DEFAULT_EPOCHS, MIN_TARGET_EXAMPLES // n_train_examples)
elif n_train_examples * TARGET_EPOCHS > MAX_TARGET_EXAMPLES:
    n_epochs = max(MIN_DEFAULT_EPOCHS, MAX_TARGET_EXAMPLES // n_train_examples)

n_billing_tokens_in_dataset = sum(min(MAX_TOKENS_PER_EXAMPLE, length) for length in convo_lens)
print(f"Dataset has ~{n_billing_tokens_in_dataset} tokens that will be charged for during training")
print(f"By default, you'll train for {n_epochs} epochs on this dataset")
print(f"By default, you'll be charged for ~{n_epochs * n_billing_tokens_in_dataset} tokens")

创建 fine-tuning

上传文件

import openai
openai.api_key = os.getenv("OPENAI_API_KEY")
test_data_file_object = openai.File.create(
  file=open(data_path, "rb"),
  purpose='fine-tune'
)

创建 fine-tuning 任务

获取文件ID

file_id = test_data_file_object.id

创建 fine-tuning

job_response = openai.FineTuningJob.create(training_file=file_id, model="gpt-3.5-turbo")

# 可选选项

# 列出10个 fine-tuning 任务
# openai.FineTuningJob.list(limit=10)

# 检索 fine-tune 的状态
# openai.FineTuningJob.retrieve(file_id)

# 终止一个任务
# openai.FineTuningJob.cancel(file_id)

# 列出 fine-tuning 任务中最多10个事件
# openai.FineTuningJob.list_events(id=file_id, limit=10)

# 删除一个 fine-tuned 模型 (但该模型必须是你创建的)
# openai.Model.delete(file_id)

使用 fine-tuned 模型

job_id = job_response.id

response_retrieve = openai.FineTuningJob.retrieve(job_id)

fine_tuned_model = response_retrieve.fine_tuned_model

completion = openai.ChatCompletion.create(
  model=fine_tuned_model,
  messages=[
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "Hello!"}
  ]
)
print(completion.choices[0].message)
{
  "role": "assistant",
  "content": "Hi there! How can I assist you today?"
}

langchain使用fine-tuned模型

from langchain.chains import LLMChain
from langchain.chat_models import ChatOpenAI
from langchain.schema import SystemMessage
from langchain.prompts import ChatPromptTemplate, HumanMessagePromptTemplate, MessagesPlaceholder
from langchain import chat_models
from langchain.memory import ConversationBufferMemory
prompt = ChatPromptTemplate.from_messages(
    [
      # system消息
      SystemMessage(content="You are a helpful AI bot."),
      # 历史记录(记忆)
      MessagesPlaceholder(variable_name="chat_history"),
      # 用户输入
      HumanMessagePromptTemplate.from_template("Extract triplets from the following sentence:{human_input}"),
    ]
)
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
llm = chat_models.ChatOpenAI(model=fine_tuned_model, temperature=0)
llm_chain = LLMChain(
    llm=llm, 
    prompt=prompt, 
    memory=memory,
    verbose=True
)
llm_chain.run("sam is a teacher")

> Entering new LLMChain chain...
Prompt after formatting:
System: You are a helpful AI bot.
Human: Extract triplets from the following sentence:sam is a teacher

> Finished chain.
- (sam, is, teacher)\n- (sam, a, teacher)
llm_chain.run("Tom is Sam's teacher")

> Entering new LLMChain chain...
Prompt after formatting:
System: You are a helpful AI bot.
Human: sam is a teacher
AI: - (sam, is, teacher)
- (sam, a, teacher)
Human: Extract triplets from the following sentence:Tom is Sam's teacher

> Finished chain.
- (Tom, is, teacher)\n- (Tom, is, Sam's teacher)\n- (Sam, 's, teacher)

标签:content,messages,LangChain,tuned,tokens,3.5,role,print,message
From: https://www.cnblogs.com/ryukirin/p/17726433.html

相关文章

  • Next.js 13.5 正式发布,速度大幅提升!
    9月19日,Next.js13.5正式发布,该版本通过以下方式提高了本地开发性能和可靠性:本地服务器启动速度提高22%:使用App和PagesRouter可以更快地进行迭代HMR(快速刷新)速度提高29%:在保存更改时进行更快的迭代内存使用量减少40%:在运行nextstart时测量优化的包导入:使用......
  • JeecgBoot v3.5.5 版本发布,性能大升级版本—开源免费的低代码开发平台
    项目介绍JeecgBoot是一款企业级的低代码平台!前后端分离架构SpringBoot2.x,SpringCloud,AntDesign&Vue3,Mybatis-plus,Shiro,JWT支持微服务。强大的代码生成器让前后端代码一键生成!JeecgBoot引领低代码开发模式(OnlineCoding->代码生成->手工MERGE),帮助解决Java项目70%的重复......
  • LangChain开发环境准备-AI大模型私有部署的技术指南
    LangChain开发环境准备-AI大模型私有部署的技术指南今天开始小智将开启系列AI应用开发课程,主要基于LangChain框架基于实战项目手把手教大家如何将AI这一新时代的基础设施应用到自己开发应用中来。欢迎大家持续关注当下在AI应用开发领域,LangChain框架可以说是唯一选择。然而,上......
  • GPT之路(八) LangChain - Models入门
    环境:Python3.11.4,LangChain0.0.270,Jupyter Models模型简介官方地址:LangChian-ModelsLangchain所封装的模型分为两类:大语言模型(LLM)聊天模型(ChatModels)Langchain的支持众多模型供应商,包括OpenAI、ChatGLM、ModelScope、HuggingFace等。后面的示例我将以OpenA......
  • GPT之路(七) LangChain AI编成框架入门的第一个demo
    环境:Python3.11.4,LangChain0.0.2701.Langchain简介1.1 PythonLangchain官方文档大型语言模型(LLM)正在成为一种具有变革性的技术,使开发人员能够构建以前无法实现的应用程序。然而,仅仅依靠LLM还不足以创建一个真正强大的应用程序。它还需要其他计算资源或知识来源。Langch......
  • 3.5 Java关系运算符
    关系运算符(relationaloperators)也可以称为“比较运算符”,用于用来比较判断两个变量或常量的大小。关系运算符是二元运算符,运算结果是boolean型。当运算符对应的关系成立时,运算结果是true,否则是false。关系表达式是由关系运算符连接起来的表达式。关系运算符中“关系”二字的......
  • Windows Server 2012 R2 Standard 安装.net 3.5
    很久没截图IIS部署了,最近临时接了一个部署任务就是在一台新的WindowsServer2012 R2 上部署一套系统,需要安装的.net3.5但是一直不成功,找了很久的资料终于有着落了,先记录下正常情况安装大概率都会出现以下问题 然后网上找寻解决方案方法一【无效】:角色添加功能里边(就......
  • 安装langchain-chatchat
    1、下载langchain-chatchatgitclonehttps://github.com/chatchat-space/Langchain-Chatchat.git2、下载llama2-7b-chat-hfgitlfsinstallgitclonehttps://huggingface.co/meta-llama/Llama-2-7b-chat-hf以上下载不成功,找到百度网盘版本,改用:wget传输文件压缩成tar,传输。......
  • SI3262 低功耗 SOC +13.56mhz刷卡+触摸三合一芯片,适用于智能锁方案
    Si3262是一款高度集成的低功耗SOC芯片,其集成了基于RISC-V核的低功耗MCU和工作在13.56MHz的非接触式读写器模块。MCU模块具有低功耗、LowPinCount、宽电压工作范围,集成了13/14/15/16位精度的ADC、LVD、UART、SPI、I2C、TIMER、WUP、IWDG、RTC、TSC等丰富的外设。内核......
  • 电气工程师必学------CODESYS v3.5 入门学习笔记(一)
    一、新建工程打开软件新建工程,如图此教程只是入门练习,所以这里一般情况下都是创建的Standardproject,也就是标准工程。窗口下方可以设置工程名称与存放位置。紧接着是选择设备与编译语言。初学者条件有限就直接上仿真,电脑是windowsx64的话设备选择上图所示就OK。语言这里我......