新智元報導。
修改:桃子 好困。更新
【新智元導讀】。更新pg電子·(中國)娛樂官方網站今日,更新OpenAI正式敞開GPT-3.5微調API,更新GPT-4版別也行將推出。更新這意味著,更新繼插件「APP Store」大迸發后,更新一切人皆能夠打造個性化的更新專屬「類ChatGPT運用」。
總算來了!更新
剛剛,更新OpenAI正式宣告,更新一切開發者都能夠對GPT-3.5 Turbo進行微調。更新
開端成果標明,微調后的更新GPT-3.5 Turbo,在詳細使命中,功用與GPT-4實力適當,乃至反超GPT-4。
最讓人振奮的是,「地表最強」的GPT-4微調版別,也將在幾個月后正式上線。
這意味著,任何人能夠依據需求,用「專有數據」對模型微調,標志著OpenAI敞開了AI商業運用的新紀元。
英偉達高檔科學家Jim Fan稱,OpenAI發布了自「插件運用商鋪」以來最大的產品更新:GPT-3.5的微調API。這將是有史以來最大的LoRA云服務。估量將有一大堆新運用從各行各業呈現出來。
提示量大減90%。
自GPT-3.5 Turbo發布以來,開發者和企業一直在尋求定制化的模型,以便為用戶創立共同和差異化的體會。
不負等候,現在,開發者總算能夠進行監督式微調,讓該模型更好地滿意自己的運用需求。
OpenAI標明,在私家測驗版中,客戶現現已過微調,顯著提升了模型在常見事例中的功用,詳細包括:
- 進步可控性。
AI模型面對的經典應戰之一,便是精確地遵從指令。而微調便能夠讓模型做到這一點,比方輸出愈加簡練,或一直用特定的言語回復。
舉個栗子,開發者能夠經過微調保證要求模型,當用戶在運用德語時,模型總是以德語回應。
- 牢靠的輸出格局。
微調進步了模型共同格局化呼應的pg電子·(中國)娛樂官方網站才干,這關于需求特定呼應格局的APP十分重要,比方代碼補全或編寫API調用。
幻想一下,開發者能夠經過微調將用戶提示牢靠地轉化為高質量的JSON片段,這樣,就能與自己的體系一同運用,讓使命變得愈加流通。
- 自定義語調。
微調能夠優化模型,輸出能夠反響特定語調,然后更好地代表習慣企業品牌的聲響。
不同的品牌對外宣告的聲響是紛歧樣的,從活潑立異草創公司到較為保存的企業,都能夠經過模型微調讓語調與對外形象保持共同。
- 更短的提示,相同的功用。
GPT-3.5-Turbo微調能夠處理多達4k個token,是之前微調模型的2倍。
前期測驗者經過指令微調模型自身,將提示巨細削減了高達90%,然后加快了每次API調用,并下降了本錢。
值得注意的是,當微調與提示工程、信息檢索和函數調用等其他技能相結合時,會取得最為強壯的才干。
最終OpenAI標明,支撐運用函數調用和gpt-3.5-turbo-16k的微調功用,也將在本年秋季推出。
價格x8。
微調GPT-3.5的本錢能夠分為兩部分:初始練習本錢和運用本錢。
練習:0.008美元/1K token。
運用輸入:0.012美元/1K token。
運用輸出:0.016美元/1K token。
例如,一個gpt-3.5-turbo微調使命的練習文件為100,000個token(約75,000個單詞),那么練習3個epoch的預期本錢為2.40美元。
從運用的價格上來看,微調后的GPT-3.5是原始版別的8倍。
四步輕松搞定。
第一步:預備數據。
第二步:上傳文件。
第三步:創立微調使命。
第四步:運用微調模型。
GPT-3模型更新。
7月,OpenAI曾宣告GPT-3根底模型(ada、babbage、curie和davinci)將于2024年1月4日封閉。
同在今日,OpenAI再次更新GPT-3模型,并供給了babbage-002和davinci-002作為以上模型替代品,能夠作為根底模型或微調模型來運用。
客戶也能夠經過查詢Completions API來訪問這些模型。
別的,這些模型運用新的API端口/v1/fine_tuning/jobs進行微調。
該端口替代了/v1/fine-tunes舊端口(2024年1月4日封閉),供給了分頁和更多可擴展性,以支撐微調API的未來開展。
網友敞開新世界。
很多網友現已依據GPT-3.5 Turbo微調功用,開端發明新世界了。
剛剛在依據Marv示例的組成樣本數據上對GPT-3.5進行了微調,Marv太搞笑了。
用戶:我怎樣才干交到女朋友?
幫手:嘿Siri,給我找個女朋友。
毋庸置疑,這將徹底改變游戲規則,大大削減咱們的API本錢!
不過,也有網友標明十分疑問,假如GPT-3.5 Turbo比GPT-4還強,那為什么還要每月付出20美元???
對此其他網友解釋道,它只是在「特定使命」上更勝一籌,在通用型使命上仍然仍是GPT-4的主場。
官方微調攻略。
怎么去微調GPT-3.5 Turbo,官方現已給出了教程。
地址:https://platform.openai.com/docs/guides/fine-tuning。
首要,OpenAI介紹了經過微調,你能夠API可用的模型中取得更多信息:
1. 比提示質量更高的成果。
2. 能夠就提示中無法包容的更多示例進行練習。
3. 提示更簡練,節約token運用。
4. 下降推遲懇求。
GPT模型現已在很多文本進步行了預練習。
為了有用運用模型,OpenAI在提示中參加指令,有時還包括幾個示例。經過演示,來展現模型怎么履行使命一般被稱為「少樣本學習」。
微調能夠經過練習比提示中更多的示例,來改善少樣本學習,能夠讓模型在很多使命上取得更好的成果。
一旦微調模型,你就不需求在提示符中供給更多的示例。這樣,既節約了本錢,又下降了推遲的懇求。
在高層次上,微調包括以下過程:
1. 預備和上傳練習數據。
2. 練習一個新的微調模型。
3. 運用你的微調模型。
現在,微調可用于以下模型:
- gpt-3.5-turbo-0613(引薦)。
- babbage-002。
- davinci-002。
何時需求微調。
微調GPT模型能夠使其更合適特定APP,但這需求投入很多的時刻和精力。
OpenAI主張,首要測驗經過提示工程、提示鏈(將雜亂使命分解為多個提示),以及函數調用,能夠取得杰出的成果,首要原因是:
- 有許多使命,GPT模型開端或許體現欠安,但有了更好的提示,便能夠取得更好的成果,而且或許不需求微調。
- 迭代提示等其他戰略,比運用微調迭代具有更快的反應循環,而微調需求創立數據集,而且練習模型。
- 在仍需求微調的狀況下,初始提示工程使命不會白搭。OpenAI一般在微調數據中運用優異的提示(或將提示鏈/東西運用與微調相結合),然后看到最佳成果。
前段時刻,OpenAI發布「GPT最佳實踐攻略」中,供給一些有關提示有用的戰略,無需微調即可取得更好的功用。
https://platform.openai.com/docs/guides/gpt-best-practices。
常見用例。
微調能夠改善成果的一些常見用例:
- 設置風格、語調、格局或其他定性方面。
- 進步出產所需輸出的牢靠性。
- 糾正不按雜亂提示操作的狀況。
- 以特定方法處理許多邊際狀況。
- 履行一項難以用提示表達的新技能或使命。
在接下來的部分中,OpenAI將討論怎么設置用于微調的數據,以及微調后進步基線模型功用的各種示例。
微調有用的另一個場景是,在不獻身質量的狀況下經過替換GPT-4,或運用更短的提示來下降本錢和/或推遲。
假如能夠用GPT-4取得杰出的成果,那么經過對GPT-4完結進行微調(或許運用更短的指令提示),而微調gpt-3.5-turbo后模型也能到達類似的作用。
預備數據集。
當你承認微調是正確的解決方案,將需求預備練習模型的數據。
這兒,你需求創立一組多樣化的演示對話,這些對話應與你在推理時要求模型呼應的對話類似。
數據會集的每個示例都應該是,與Chat completions API相同的對話,詳細來說,便是一個音訊列表,每個音訊都有人物、內容和可選稱號。
至少一些練習示例,應該直接針對提示模型行為不符合預期的狀況,而且數據中供給的幫手音訊,應該是你期望模型供給的抱負呼應。
- 示例格局。
在這個比如中,方針是創立一個偶然給出挖苦回應的談天機器人。
對此,OpenAI為數據集創立了3個練習示例(對話):
{"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."}]}。
微調gpt-3.5-turbo需求會話談天格局。關于babbage-002和davinci-002,你能夠依照用于舊版微調的提示完結配對格局,如下:
{"prompt": "", "completion": ""}。
{"prompt": "", "completion": ""}。
{"prompt": "", "completion": ""}。
- 編寫提示。
主張在微調之前,用你以為對模型最有用的指令和提示,歸入到每個練習示例中。
這樣做能夠取得最佳和最遍及的成果,尤其是在練習示例相對較少(缺乏100個)的狀況下。
假如你想縮短每個示例中重復呈現的指令或提示,以節約本錢,請記住,模型的行為很或許包括這些指令,很難讓模型在推理時疏忽這些「內置」指令。
或許需求更多的練習示例才干取得杰出的成果,由于模型有必要徹底經過演示學習,而無需指令輔導。
- 示例數量。
要微調模型,你需求供給至少10個示例。
一般會看到,運用gpt-3.5-turbo對50-100個練習示例進行微調,有著顯著改善。依據詳細運用狀況,相同的的示例作用紛歧。
OpenAI主張,從50個精心制作示例開端,看看模型在微調后是否顯現出改善的痕跡。
在某些狀況下,這或許就足夠了,但即便模型沒有到達輸出質量,清晰的改善也是一個好痕跡,標明供給更多數據將持續改善模型。
假如沒有改善,則標明你或許需求從頭考慮怎么為模型設置使命,或許在擴展到有限的示例集之前,從頭調整數據結構。
- 拆分練習和測驗。
搜集初始數據集后,主張將其拆分為練習和測驗兩個部分。
當提交包括練習和測驗文件的微調時,OpenAI將在練習過程中供給兩者的統計數據。
這些統計數據將是模型改善程度的初始信號。
此外,經過在測驗集上生成樣本,盡早構建測驗集將有助于保證你能夠在練習后評價模型。
- token約束。
每個練習示例約束為4096個token。
練習時,長度超越這一約束,將被切斷為4096個token。
因而,要保證整個練習示例合適上下文,請查看音訊內容中的總token數是否低于4,000個。每個文件當時約束為50 MB。
- 預算本錢。
為了預算微調本錢,首要仍是參閱官方定價頁面,了解每1k token本錢的詳細信息。
在3個epoch內練習了100,000個token的練習文件,預期本錢約為2.4美元。
- 查看數據格局。
編譯完數據集后,在創立微調之前,查看數據格局十分重要。
為此,OpenAI創立了一個簡略的Python腳本,你能夠運用它來查找潛在過錯、查看token計數并估量微調的本錢。
數據格局化腳本:
# We start by importing the required packages。
import json。
import os。
import tiktoken。
import numpy as np。
from collections import defaultdict。
# Next, we specify the data path and open the JSONL file。
data_path = ""。
# Load dataset。
with open(data_path) as f:。
dataset = [json.loads(line) for line in f]。
# We can inspect the data quickly by checking the number of examples and the first item。
# Initial dataset stats。
print("Num examples:", len(dataset))。
print("First example:")。
for message in dataset[0]["messages"]:。
print(message)。
# Now that we have a sense of the data, we need to go through all the different examples and check to make sure the formatting is correct and matches the Chat completions message structure。
# Format error checks。
format_errors = defaultdict(int)。
for ex in dataset:。
if not isinstance(ex, dict):。
format_errors["data_type"] += 1。
continue。
messages = ex.get("messages", None)。
if not messages:。
format_errors["missing_messages_list"] += 1。
continue。
for message in messages:。
if "role" not in message or "content" not in message:。
format_errors["message_missing_key"] += 1。
if any(k not in ("role", "content", "name") for k in message):。
format_errors["message_unrecognized_key"] += 1。
if message.get("role", None) not in ("system", "user", "assistant"):。
format_errors["unrecognized_role"] += 1。
content = message.get("content", None)。
if not content or not isinstance(content, str):。
format_errors["missing_content"] += 1。
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")。
# Beyond the structure of the message, we also need to ensure that the length does not exceed the 4096 token limit.。
# Token counting functions。
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: , ")。
print(f"mean / median: {np.mean(values)}, {np.median(values)}")。
print(f"p5 / p95: {np.quantile(values, 0.1)}, {np.quantile(values, 0.9)}")。
# Last, we can look at the results of the different formatting operations before proceeding with creating a fine-tuning job:。
# Warnings and tokens counts。
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")。
# Pricing and default n_epochs estimate。
MAX_TOKENS_PER_EXAMPLE = 4096。
MIN_TARGET_EXAMPLES = 100。
MAX_TARGET_EXAMPLES = 25000。
TARGET_EPOCHS = 3。
MIN_EPOCHS = 1。
MAX_EPOCHS = 25。
n_epochs = TARGET_EPOCHS。
n_train_examples = len(dataset)。
if n_train_examples * TARGET_EPOCHS < MIN_TARGET_EXAMPLES:。
n_epochs = min(MAX_EPOCHS, MIN_TARGET_EXAMPLES // n_train_examples)。
elif n_train_examples * TARGET_EPOCHS > MAX_TARGET_EXAMPLES:。
n_epochs = max(MIN_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")。
print("See pricing page to estimate total costs")。
驗證數據后,需求上傳文件才干與微調一同運用:
openai.File.create(。
file=open("mydata.jsonl", "rb"),
purpose='fine-tune'。
創立微調模型。
在保證數據集的數量和結構正確并上傳文件后,下一步是創立微調模型。
運用OpenAI SDK開端微調:
import os。
import openai。
openai.api_key = os.getenv("OPENAI_API_KEY")。
openai.FineTuningJob.create(training_file="file-abc123", model="gpt-3.5-turbo")。
其間,model是初始的模型的稱號(gpt-3.5-turbo、babbage-002或davinci-002)。你能夠運用后綴參數自定義微調模型的稱號。
開端微調后,或許需求一些時刻才干完結。
依據模型和數據集的巨細,練習模型或許需求幾分鐘,或幾個小時。模型練習完結后,創立微調模型的用戶將收到一封電子郵件承認。
除了創立微調模型之外,你還能夠列呈現有使命、檢索使命狀況或撤銷使命。
# List 10 fine-tuning jobs。
openai.FineTuningJob.list(limit=10)。
# Retrieve the state of a fine-tune。
openai.FineTuningJob.retrieve("ft-abc123")。
# Cancel a job。
openai.FineTuningJob.cancel("ft-abc123")。
# List up to 10 events from a fine-tuning job。
openai.FineTuningJob.list_events(id="ft-abc123", limit=10)。
# Delete a fine-tuned model (must be an owner of the org the model was created in)。
import openai。
openai.Model.delete("ft-abc123")。
運用微調模型。
使命成功后,在檢索作業詳細信息時,你將看到fine_tuned_model字段填充了模型的稱號。
你現在能夠將此模型指定為Chat完結(用于gpt-3.5-turbo)或舊Completions API(用于babbage-002和davinci-002)中的參數,并運用Playground向其宣告懇求。
一切過程完結后,模型能夠當即用于推理。
在某些狀況下,你的模型或許需求幾分鐘才干預備好處理懇求。假如對模型的懇求超時或找不到模型稱號,很或許是由于模型仍在加載中。假如產生這種狀況,請在幾分鐘后重試。
import os。
import openai。
openai.api_key = os.getenv("OPENAI_API_KEY")。
completion = openai.ChatCompletion.create(。
model="ft:gpt-3.5-turbo:my-org:custom_suffix:id",
messages=[。
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello!"}。
print(completion.choices[0].message)。
微調示例。
- 風格和語調。
在這個比如中,將討論怎么樹立一個微調模型,讓模型遵從特定的風格和語調輔導,而不是只是依托提示。
首要,創立一組示例對話,顯現模型應該是什么,如下這個比如是「拼寫過錯的單詞」。
{"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."}]}。
假如你想仿效并自己創立一個微調模型,至少需求10個示例。
在取得或許改善模型的數據后,下一步是查看數據是否滿意一切格局要求。
在對數據進行了格局化和驗證,最終的練習過程是開端創立微調模型。你能夠經過OpenAI CLI或SDK之一履行此操作,如下所示:
openai.File.create(file=open("marv.jsonl", "rb"), purpose='fine-tune')。
openai.FineTuningJob.create(training_file="file-abc123", model="gpt-3.5-turbo")。
一旦練習完結后,你就能夠運用自己的微調模型。
- 結構化輸出。
另一種與微調十分有用的用例是讓模型供給結構化信息,如下比如是關于「體育新聞標題」:
{"messages": [{"role": "system", "content": "Given a sports headline, provide the following fields in a JSON dict, where applicable: "player" (full name)", "team", "sport", and "gender".},{"role": "user", "content": "Sources: Colts grant RB Taylor OK to seek trade"},
{"role": "assistant", "content": "{"player": "Jonathan Taylor", "team": "Colts", "sport": "football", "gender": "male"}"},]}。
{"messages": [{"role": "system", "content": "Given a sports headline, provide the following fields in a JSON dict, where applicable: "player" (full name)", "team", "sport", and "gender".},{"role": "user", "content": "OSU 'split down middle' on starting QB battle"},
{"role": "assistant", "content": "{"player": null, "team": "OSU", "sport": "football", "gender": null}"},]}。
接下來的過程,如上一個比如:
openai.File.create(file=open("sports-context.jsonl", "rb"), purpose='fine-tune')。
openai.FineTuningJob.create(training_file="file-abc123", model="gpt-3.5-turbo")。
練習完結后,你能夠運用微調模型,并提出一下懇求:
import os。
import openai。
openai.api_key = os.getenv("OPENAI_API_KEY")。
completion = openai.ChatCompletion.create(。
model="ft:gpt-3.5-turbo:my-org:custom_suffix:id",
messages=[。
{"role": "system", "content": "Given a sports headline, provide the following fields in a JSON dict, where applicable: player (full name), team, sport, and gender"},
{"role": "user", "content": "Richardson wins 100m at worlds to cap comeback"}。
print(completion.choices[0].message)。
依據格局化的練習數據,呼應應如下所示:
{"player": "Sha'Carri Richardson", "team": null", "sport": "track and field", "gender": "female"}。
除此之外,在GitHub上斬獲了近47k星的「OpenAI Cookbook」(OpenAI API的運用示例和攻略),也于第一時刻收拾出了一份翔實的微調教程。
項目地址:https://github.com/openai/openai-cookbook/blob/main/examples/How_to_finetune_chat_models.ipynb。
參閱資料:
下一篇:西北政法大學2024保研數據,保送105人,2人被保送到北京大學
上一篇:扎心,一老師發現兒子數學考18分,不敢跟孩子班主任說自己是教師