Eine der häu­figs­ten Fra­gen, die ich von Kun­den bekomme, lau­tet: „Wie kann ich einen benut­zer­de­fi­nier­ten Chat­bot mit mei­nen Daten erstel­len?“ Wäh­rend die Ent­wick­lung eines sol­chen Chat­bots vor 6 Mona­ten noch Monate dau­erte, ist das heute nicht mehr unbe­dingt der Fall. In die­sem Arti­kel stelle ich eine Schritt-für-Schritt-Anlei­tung vor, wie man eine benut­zer­de­fi­nierte KI mit­hilfe der Ope­nAI-Assis­ten­ten und Fein­ab­stim­mungs-APIs erstellt. Für jeden Ansatz wird Python-Bei­spiel­code bereitgestellt.

Chat­bot vs. Assistent

Bevor ich auf den Bei­spiel­code ein­gehe, möchte ich kurz zwi­schen einem KI-Chat­bot und einem Assis­ten­ten unter­schei­den. Obwohl diese Begriffe oft syn­onym ver­wen­det wer­den, bezeichne ich sie hier für unter­schied­li­che Dinge.

Ein Chat­bot ist eine KI, mit der man eine Unter­hal­tung füh­ren kann, wäh­rend ein KI-Assis­tent ein Chat­bot ist, der Tools ver­wen­den kann. Ein Tool kann z. B. das Sur­fen im Inter­net, ein Taschen­rech­ner, ein Python-Inter­pre­ter oder etwas ande­res sein, das die Fähig­kei­ten eines Chat­bots erwei­tert [1].

Wenn Sie z. B. die kos­ten­lose Ver­sion von ChatGPT ver­wen­den, han­delt es sich um einen Chat­bot, da er nur über eine grund­le­gende Chat­funk­tion ver­fügt. Wenn Sie jedoch die Pre­mium-Ver­sion von ChatGPT ver­wen­den, han­delt es sich um einen Assis­ten­ten, da er über Funk­tio­nen wie Web­brow­sing, Wis­sens­ab­frage und Bil­der­zeu­gung verfügt.

Assis­ten­ten-API

Die Idee, KI-Assis­ten­ten (d.h. KI-Agen­ten) zu ent­wi­ckeln, ist zwar nicht neu, aber die neue Assis­ten­ten-API von Ope­nAI bie­tet eine unkom­pli­zierte Mög­lich­keit, diese Art von KI zu erstel­len. Hier werde ich die API ver­wen­den, um einen You­Tube-Kom­men­tar-Respon­der zu erstel­len, der mit Wis­sens­ab­frage (d.h. RAG) aus einem mei­ner Medium-Arti­kel aus­ge­stat­tet ist. Der fol­gende Bei­spiel­code ist im Git­Hub-Repo­si­tory die­ses Bei­trags verfügbar.

Vanilla-Assis­tent
Wir begin­nen mit dem Impor­tie­ren von Python-Biblio­the­ken und dem Ein­rich­ten der Kom­mu­ni­ka­tion mit der OpenAI-API.

from openai import OpenAI
from sk import my_sk # import secret key from .py file

client = OpenAI(api_key=my_sk)

Beach­ten Sie, dass Sie für die­sen Schritt einen Ope­nAI-API-Schlüs­sel benö­ti­gen. Wenn Sie kei­nen API-Schlüs­sel haben oder nicht wis­sen, wie Sie einen bekom­men, habe ich in einem frü­he­ren Arti­kel beschrie­ben, wie man das macht. Hier habe ich mei­nen gehei­men Schlüs­sel in einer sepa­ra­ten Python-Datei namens sk.py defi­niert, die im obi­gen Code­block impor­tiert wurde.

Jetzt kön­nen wir einen ein­fa­chen Assis­ten­ten erstel­len (tech­nisch gese­hen einen Chat­bot, da es noch keine Tools gibt). Dies kann in einer ein­zi­gen Code­zeile gesche­hen, aber ich ver­wende aus Grün­den der Les­bar­keit ein paar mehr.

intstructions_string = "ShawGPT, functioning as a virtual data science \
consultant on YouTube, communicates in clear, accessible language, escalating \
to technical depth upon request. \
It reacts to feedback aptly and concludes with its signature '–ShawGPT'. \
ShawGPT will tailor the length of its responses to match the viewer's comment, \
providing concise acknowledgments to brief expressions of gratitude or \
feedback, thus keeping the interaction natural and engaging."

assistant = client.beta.assistants.create(
    name="ShawGPT",
    description="Data scientist GPT for YouTube comments",
    instructions=intstructions_string,
    model="gpt-4-0125-preview"
)

Wie oben dar­ge­stellt, kön­nen wir den Namen des Assis­ten­ten, die Beschrei­bung, die Anwei­sun­gen und das Modell fest­le­gen. Die Ein­ga­ben, die für die Leis­tung des Assis­ten­ten am wich­tigs­ten sind, sind die Anwei­sun­gen und das Modell. Die Ent­wick­lung guter Anwei­sun­gen (d. h. Prompt-Engi­nee­ring) ist ein ite­ra­ti­ver Pro­zess, für den es sich lohnt, einige Zeit auf­zu­wen­den. Außer­dem ver­wende ich die neu­este ver­füg­bare Ver­sion von GPT‑4. Es sind jedoch auch ältere (und bil­li­gere) Modelle erhält­lich [2].

Nach­dem der „Assis­tent“ ein­ge­rich­tet ist, kön­nen wir ihm eine Nach­richt schi­cken, um eine Ant­wort zu erzeu­gen. Dies geschieht im fol­gen­den Codeblock.

# create thread (i.e. object that handles conversation between user and assistant)
thread = client.beta.threads.create()

# add a user message to the thread
message = client.beta.threads.messages.create(
    thread_id=thread.id,
    role="user",
    content="Great content, thank you!"
)

# send message to assistant to generate a response
run = client.beta.threads.runs.create(
  thread_id=thread.id,
  assistant_id=assistant.id,
)

In dem obi­gen Code­block pas­sie­ren einige Dinge. Zunächst erstel­len wir ein Thread-Objekt. Damit wird der Nach­rich­ten­aus­tausch zwi­schen dem Benut­zer und dem Assis­ten­ten abge­wi­ckelt, so dass wir dafür kei­nen Boi­ler­p­late-Code schrei­ben müs­sen. Als nächs­tes fügen wir dem Thread eine Benut­zer­nach­richt hinzu. Dies sind die You­Tube-Kom­men­tare für unse­ren Anwen­dungs­fall. Schließ­lich sen­den wir den Thread an den Assis­ten­ten, um über das Run-Objekt eine Ant­wort zu erzeugen.

Nach ein paar Sekun­den erhal­ten wir die fol­gende Ant­wort vom Assistenten:

You're welcome! I'm glad you found it helpful. If you have any more questions 
or topics you're curious about, feel free to ask. –ShawGPT

Das mag zwar wie eine nette Ant­wort klin­gen, aber das ist nichts, was ich jemals sagen würde. Schauen wir uns an, wie wir den Assis­ten­ten durch das so genannte „few-shot promp­ting“ ver­bes­sern können.

Few-Shot-Promp­ting
Beim Few-shot Promp­ting fügen wir den Anwei­sun­gen des Assis­ten­ten Bei­spiele für Ein­ga­ben und Aus­ga­ben hinzu, aus denen er ler­nen kann. Hier füge ich 3 (echte) Kom­men­tare und Ant­wor­ten an die vor­he­rige Anwei­sung an.

intstructions_string_few_shot = """ShawGPT, functioning as a virtual data \
science consultant on YouTube, communicates in clear, accessible language, \
escalating to technical depth upon request. \
It reacts to feedback aptly and concludes with its signature '–ShawGPT'. \
ShawGPT will tailor the length of its responses to match the viewer's comment, \
providing concise acknowledgments to brief expressions of gratitude or \
feedback, thus keeping the interaction natural and engaging.

Here are examples of ShawGPT responding to viewer comments.

Viewer comment: This was a very thorough introduction to LLMs and answered many questions I had. Thank you.
ShawGPT: Great to hear, glad it was helpful :) -ShawGPT

Viewer comment: Epic, very useful for my BCI class
ShawGPT: Thanks, glad to hear! -ShawGPT

Viewer comment: Honestly the most straightforward explanation I've ever watched. Super excellent work Shaw. Thank you. It's so rare to find good communicators like you!
ShawGPT: Thanks, glad it was clear -ShawGPT"""

Beach­ten Sie, dass ich jedes Bei­spiel mit dem Zusatz „- ShawGPT“ ver­se­hen habe (auch wenn sie nicht Teil mei­ner eigent­li­chen Ant­wort waren). Dies ist wich­tig, um das gewünschte Ver­hal­ten des Assis­ten­ten zu erreichen.

Mit den aktua­li­sier­ten Anwei­sun­gen kön­nen wir einen neuen Assis­ten­ten auf die glei­che Weise wie zuvor erstellen.

assistant = client.beta.assistants.create(
    name="ShawGPT",
    description="Data scientist GPT for YouTube comments",
    instructions=intstructions_string_few_shot,
    model="gpt-4-0125-preview"
)

Wenn wir den­sel­ben Test­kom­men­tar (z. B. „Great con­tent, thank you!“) wie zuvor an die­sen Assis­ten­ten wei­ter­ge­ben, erhal­ten wir nun die fol­gende Antwort:

You're welcome, happy to hear you found it useful! -ShawGPT

Das ist zwar (noch) etwas län­ger als meine typi­sche Ant­wort, aber viel bes­ser als das, was wir mit dem Vanilla Assistant gese­hen haben.

Ver­su­chen wir es mit einer ande­ren (eher tech­ni­schen) Frage. Wir kön­nen die­selbe Syn­tax wie zuvor ver­wen­den, um die Benut­zer­nach­richt an den Assis­ten­ten zu über­mit­teln, aber jetzt fra­gen wir: „Was ist Fat-Tailedness?“

Hier ist die Ant­wort des Assistenten.

Fat-tailedness is a concept from statistics that refers to the properties of a 
particular type of probability distribution. In a fat-tailed distribution, the 
tails (the far ends of the distribution, representing extreme values far from 
the mean) are heavier or "fatter" than they would be in a normal (Gaussian) 
distribution. This means there's a higher likelihood of extreme outcomes 
occurring compared to what you would expect if the data followed a normal 
distribution.

In practical terms, if a dataset is described as having a fat-tailed 
distribution, it indicates that rare, extreme events (the ones in the tails) 
happen more frequently than would be predicted by models based on normal 
distributions. This concept is extremely important in fields like finance, 
economics, and risk management, where underestimating the likelihood of extreme
events can have significant consequences.

Fat-tailed distributions contrast with thin-tailed distributions, like the 
normal distribution, where extreme values are less likely, and most of the 
probabilities are concentrated around the mean. Understanding whether a dataset
follows a fat-tailed distribution can significantly impact how we model and 
predict phenomena, especially when it comes to assessing risks and anticipating
rare but impactful events. -ShawGPT

Auch wenn diese Ant­wort (wie­der) ver­nünf­tig ist, liest sie sich eher wie etwas aus ChatGPT als das, was ich sagen würde. Sie ver­wen­det näm­lich eine andere Defi­ni­tion von „fat tails“ (d. h. eine Ver­tei­lung mit stär­ke­ren Aus­läu­fern als eine Nor­mal­ver­tei­lung) als die, die ich in mei­ner Serie zu die­sem Thema ver­wende (d. h. eine Ver­tei­lung, die von extre­men Ereig­nis­sen bestimmt wird).

Um die­sen Aspekt der Ant­wor­ten des Assis­ten­ten zu ver­bes­sern, kön­nen wir ihm die Mög­lich­keit geben, auf Wis­sen aus einem Medium-Arti­kel zuzu­grei­fen, den ich über Fat-Tail­ed­ness geschrie­ben habe.

Abru­fen von Wis­sen
Wäh­rend die Ein­rich­tung eines RAG-Sys­tems aus einer Hand­voll nicht tri­via­ler Schritte besteht (z. B. Chun­king von Doku­men­ten, Ein­rich­tung einer Vek­tor­da­ten­bank, Auf­bau einer seman­ti­schen Such­funk­tion, Zusam­men­füh­rung von Such­ergeb­nis­sen in einem Kon­text­fens­ter), wird der gesamte Pro­zess in der Assis­ten­ten-API auf zwei Schritte reduziert.

Zuerst laden wir unsere Doku­mente zum Abruf hoch. Zwei­tens haben wir unse­rem Assis­ten­ten die Such­funk­tion hinzugefügt.

Im fol­gen­den Code­block lade ich mei­nen Arti­kel über die Quan­ti­fi­zie­rung von fat tails auf mein Ope­nAI-Konto hoch. Dazu müs­sen wir den Datei­pfad/-namen und den Zweck der Datei ange­ben. Hier haben wir als Zweck „Assis­ten­ten“ ange­ge­ben. Die andere Option ist „fine-tune“, die wir bald sehen werden.

file = client.files.create(
  file=open("articles/4 Ways to Quantify Fat Tails with Python _ by Shaw Talebi _ Towards Data Science.pdf", "rb"),
  purpose="assistants"
)

Als Nächs­tes kön­nen wir einen neuen Assis­ten­ten erstel­len, ähn­lich wie zuvor, aber jetzt den Abruf akti­vie­ren und die Dateien ange­ben, die dem Assis­ten­ten zur Ver­fü­gung ste­hen. Wäh­rend ich hier nur ein Doku­ment für den Abruf ver­wende, kön­nen wir bis zu 20 Dateien ange­ben, indem wir die zuge­hö­ri­gen Datei-IDs in die file_ids-Liste auf­neh­men.

assistant = client.beta.assistants.create(
    name="ShawGPT",
    description="Data scientist GPT for YouTube comments",
    instructions=intstructions_string_few_shot,
    tools=[{"type": "retrieval"}],
    file_ids=[file.id],
    model="gpt-4-0125-preview"
)

Wenn wir die glei­che tech­ni­sche Frage an den Assis­ten­ten wei­ter­ge­ben, erhal­ten wir fol­gende Antwort.

Fat-tailedness describes the degree to which rare events significantly 
contribute to the aggregate statistics of a distribution. This concept 
highlights that in certain distributions, a small number of observations can 
disproportionately influence the overall picture. A classic example is the 
Pareto distribution, often referenced in the context of wealth distribution, 
where a small proportion of individuals can hold the majority of wealth. In 
statistical terms, distributions range from thin-tailed (e.g., Gaussian, where 
extreme events are highly improbable) to very fat-tailed (e.g., Pareto, where 
extreme events are less rare than in Gaussian distributions).

Fat-tailedness is not about a binary categorization of distributions as either 
"Power Law" or not but recognizes a continuum or spectrum of "tail heaviness." 
This understanding offers a more nuanced view, allowing for more accurate and 
precise categorization of data distributions. Identifying and quantifying the 
fat-tailed nature of a dataset is important in fields like finance, insurance, 
risk management, and social sciences, where understanding the likelihood and 
impact of extreme events is crucial.

In practical terms, fat-tailedness can be quantified using different heuristics,
which may involve mathematical computations such as the Power Law Tail Index, 
Kurtosis, Log-normal's σ, and Taleb's κ metric. Each of these measures offers 
a different lens through which to assess the fat-tailed nature of a 
distribution, thereby providing useful insights into the behavior of extreme 
events within the dataset -ShawGPT

Diese Ant­wort kommt der Art und Weise, wie ich über Fat-tail­ed­ness denke (und sie erkläre), sehr viel näher. Der Assis­tent hat die wich­tigs­ten Kon­zepte aus dem Arti­kel naht­los in seine Ant­wort über­nom­men. Zum Bei­spiel die Defi­ni­tion von Fat-Tail­ed­ness in Bezug auf sel­tene Ereig­nisse, Fat-Tail­ed­ness auf einem Spek­trum und vier Heu­ris­ti­ken für ihre Messung.

Bis zu die­sem Punkt sind wir mit Hilfe von Prompt-Engi­nee­ring und Know­ledge Retrie­val bei der Erstel­lung unse­res Assis­ten­ten schon recht weit gekom­men. Aller­dings lesen sich die Ant­wor­ten immer noch nicht ganz so, wie ich sie schrei­ben würde. Um die­sen Aspekt des Assis­ten­ten wei­ter zu ver­bes­sern, kön­nen wir uns der Fein­ab­stim­mung zuwenden.

Fein­ab­stim­mung der API

Auch wenn die Ein­ga­be­auf­for­de­rung ein ein­fa­cher Weg ist, einen Assis­ten­ten zu pro­gram­mie­ren, ist es nicht immer offen­sicht­lich, wie man das Modell am bes­ten anweist, das gewünschte Ver­hal­ten zu zei­gen. In sol­chen Situa­tio­nen kann es von Vor­teil sein, das Modell fein abzustimmen

Bei der Fein­ab­stim­mung trai­nie­ren wir ein bereits vor­han­de­nes Modell mit zusätz­li­chen Bei­spie­len für eine bestimmte Auf­gabe. In der Ope­nAI Fine-tuning API besteht dies aus der Bereit­stel­lung von Bei­spie­len für Benut­zer-Assis­ten­ten-Nach­rich­ten­paare [3].

Für den Anwen­dungs­fall des You­Tube-Kom­men­tar-Respon­ders bedeu­tet dies, dass Paare von Zuschau­er­kom­men­ta­ren (d.h. Nut­zer­nach­rich­ten) und deren zuge­hö­rige Ant­wor­ten (d.h. Assis­ten­ten-Nach­rich­ten) gesam­melt werden.

Obwohl die­ser zusätz­li­che Pro­zess der Daten­er­fas­sung im Vor­feld mehr Arbeit für die Fein­ab­stim­mung bedeu­tet, kann er zu erheb­li­chen Ver­bes­se­run­gen der Modell­leis­tung füh­ren. Im Fol­gen­den werde ich den Fein­ab­stim­mungs­pro­zess für die­sen spe­zi­el­len Anwen­dungs­fall erläutern.

Daten­vor­be­rei­tung

Um die Nach­rich­ten­paare zwi­schen Nut­zer und Assis­ten­ten zu gene­rie­ren, bin ich manu­ell durch ver­gan­gene You­Tube-Kom­men­tare gegan­gen und habe sie mit Copy-Paste in eine Tabelle ein­ge­fügt. Diese Tabelle habe ich dann als .csv-Datei expor­tiert (ver­füg­bar im GitHub-Repository).

Diese .csv-Datei ent­hält zwar alle wich­ti­gen Daten, die für die Fein­ab­stim­mung benö­tigt wer­den, kann aber nicht direkt ver­wen­det wer­den. Wir müs­sen sie zunächst in ein bestimm­tes For­mat umwan­deln, um sie an die Ope­nAI-API zu übergeben.

Genauer gesagt müs­sen wir eine .jsonl-Datei erzeu­gen, eine Text­da­tei, in der jede Zeile einem Trai­nings­bei­spiel im JSON-For­mat ent­spricht. Wenn Sie ein Python-Benut­zer sind, der mit JSON nicht ver­traut ist, kön­nen Sie es sich wie ein Wör­ter­buch vor­stel­len (d. h. eine Daten­struk­tur, die aus Schlüs­sel-Wert-Paa­ren besteht) [4].

Um unsere .csv-Datei in das erfor­der­li­che .jsonl-For­mat zu brin­gen, erstelle ich zunächst Python-Lis­ten für jede Art von Kom­men­tar. Dazu lese ich die rohe .csv-Datei Zeile für Zeile und spei­chere jede Nach­richt in der ent­spre­chen­den Liste.

import csv
import json
import random

comment_list = []
response_list = []

with open('data/YT-comments.csv', mode ='r') as file:
    file = csv.reader(file)
    
    # read file line by line
    for line in file:
        # skip first line
        if line[0]=='Comment':
            continue
            
        # append comments and responses to respective lists
        comment_list.append(line[0])
        response_list.append(line[1] + " -ShawGPT")

Um die .jsonl-Datei zu erstel­len, müs­sen wir als Nächs­tes eine Liste von Wör­ter­bü­chern erstel­len, wobei jedes Ele­ment einem Trai­nings­bei­spiel ent­spricht. Der Schlüs­sel für jedes die­ser Wör­ter­bü­cher ist „mes­sa­ges“, und der Wert ist eine (wei­tere) Liste von Wör­ter­bü­chern, die jeweils den System‑, Benut­zer- und Assis­ten­ten­mel­dun­gen ent­spre­chen. Eine visu­elle Über­sicht über diese Daten­struk­tur ist unten dargestellt.

Im Fol­gen­den fin­den Sie den Python-Code, mit dem Sie aus den Objek­ten comment_list und response_list die Liste der Bei­spiele erstel­len. Dazu wer­den comment_list und response_list Ele­ment für Ele­ment durch­lau­fen und bei jedem Schritt drei Wör­ter­bü­cher erstellt.

Diese ent­spre­chen jeweils den System‑, Benut­zer- und Assis­ten­ten­mel­dun­gen, wobei die Sys­tem­mel­dung die glei­chen Anwei­sun­gen sind, die wir für die Erstel­lung unse­res Assis­ten­ten über eine kurze Ein­ga­be­auf­for­de­rung ver­wen­det haben, und die Benut­zer-/As­sis­ten­ten­mel­dun­gen aus ihren jewei­li­gen Lis­ten stam­men. Diese Wör­ter­bü­cher wer­den dann in einer Liste gespei­chert, die als Wert für die­ses bestimmte Trai­nings­bei­spiel dient.

example_list = []

for i in range(len(comment_list)):
    # create dictionaries for each role/message    
    system_dict = {"role": "system", "content": intstructions_string_few_shot}
    user_dict = {"role": "user", "content": comment_list[i]}
    assistant_dict = {"role": "assistant", "content": response_list[i]}
    
    # store dictionaries into list
    messages_list = [system_dict, user_dict, assistant_dict]
    
    # create dictionary for ith example and add it to example_list
    example_list.append({"messages": messages_list})

Am Ende die­ses Pro­zes­ses haben wir eine Liste mit 59 Ele­men­ten, die 59 Benut­zer-Assis­tent-Bei­spiel­paa­ren ent­spre­chen. Ein wei­te­rer Schritt, der bei der Bewer­tung der Modell­leis­tung hilft, besteht darin, diese 59 Bei­spiele in zwei Daten­sätze auf­zu­tei­len, einen für das Trai­ning des Modells und den ande­ren für die Bewer­tung sei­ner Leistung.

Dies geschieht im fol­gen­den Code­block, in dem ich 9 von 59 Bei­spie­len aus example_list zufäl­lig ent­nehme und sie in einer neuen Liste namens validation_data_list spei­chere. Diese Bei­spiele wer­den dann aus example_list ent­fernt, die als Trai­nings­da­ten­satz die­nen wird.

# create train/validation split
validation_index_list = random.sample(range(0, len(example_list)-1), 9)

validation_data_list = [example_list[index] for index in validation_index_list]

for example in validation_data_list:
    example_list.remove(example)

Nach­dem wir unsere Trai­nings- und Vali­die­rungs­da­ten­sätze vor­be­rei­tet haben, kön­nen wir sie in .jsonl-Dateien schrei­ben. Dies kann auf die fol­gende Weise geschehen.

# write examples to file
with open('data/training-data.jsonl', 'w') as training_file:
    for example in example_list:
        json.dump(example, training_file)
        training_file.write('\n')

with open('data/validation-data.jsonl', 'w') as validation_file:
    for example in validation_data_list:
        json.dump(example, validation_file)
        validation_file.write('\n')

Fein­ab­stim­mungs­auf­trag
Nach­dem die Daten­vor­be­rei­tung abge­schlos­sen ist, kön­nen wir die Fein­ab­stim­mung in 2 Schrit­ten durch­füh­ren. Zunächst laden wir die Trai­nings- und Vali­die­rungs­da­teien in unser Ope­nAI-Konto hoch. Zwei­tens füh­ren wir den Trai­nings­pro­zess durch [3].

Wir laden Dateien hoch, wie wir es bei der Ein­rich­tung der Doku­men­ten­su­che für einen Assis­ten­ten getan haben, nur dass wir jetzt den Zweck der Datei als „Fein­ab­stim­mung“ fest­le­gen. Dies geschieht sowohl für den Trai­nings- als auch für den Vali­die­rungs­da­ten­satz (siehe unten).

# upload fine-tuning files
training_file = client.files.create(
  file = open("data/training-data.jsonl", "rb"),
  purpose = "fine-tune"
)

validation_file = client.files.create(
  file = open("data/validation-data.jsonl", "rb"),
  purpose = "fine-tune"
)

Jetzt kön­nen wir den Fein­ab­stim­mungs­auf­trag aus­füh­ren. Dazu müs­sen wir die Trai­nings­da­teien und das Modell ange­ben, das wir fein­ein­stel­len möch­ten. Das am wei­tes­ten fort­ge­schrit­tene Modell, das für die Fein­ab­stim­mung zur Ver­fü­gung steht, ist gpt‑3.5‑turbo, das ich hier ver­wende. Ich setze auch ein Suf­fix, das eine benut­zer­de­fi­nierte Zei­chen­folge an die ID des fein­ab­ge­stimm­ten Modells anhängt. Der Code dafür ist unten dargestellt.

client.fine_tuning.jobs.create(
    training_file = training_file.id,
    validation_file = validation_file.id,
    suffix = "ShawGPT",
    model = "gpt-3.5-turbo"
)

Der Trai­nings­pro­zess wird etwa 15 Minu­ten dau­ern. Nach Abschluss kön­nen wir das fein abge­stimmte Modell über die Abschluss-API ver­wen­den, wie unten dargestellt.

test_comment = "Great content, thank you!"

response = client.chat.completions.create(
    model="ft:gpt-3.5-turbo-0613:personal:shawgpt:8mUeVreo",
    messages=[
    {"role": "system", "content": intstructions_string_few_shot},
    {"role": "user", "content": test_comment}
    ]
)

Beach­ten Sie, dass sich die Art und Weise, wie wir die Ant­wort im obi­gen Code­block gene­rie­ren, von der bis­he­ri­gen Vor­ge­hens­weise unter­schei­det. Das liegt daran, dass fein abge­stimmte Modelle der­zeit nicht von der Assis­ten­ten-API unter­stützt werden.

Der größte Nach­teil ist, dass wir, wenn wir das fein abge­stimmte Modell mit Werk­zeu­gen erwei­tern wol­len (d. h. es zu einem Assis­ten­ten machen), diese Funk­tio­na­li­tä­ten über Biblio­the­ken wie Lang­Chain oder Llama­In­dex (zum Bei­spiel) ent­wi­ckeln müssen.

Das macht die Ent­wick­lung eines fein abge­stimm­ten Assis­ten­ten zwar auf­wän­di­ger, aber die Ant­wor­ten, die wir sehen, sind näher an dem, was ich sagen würde. Hier sind ein paar Ant­wor­ten auf den Testkommentar.

Thanks, I appreciate it! -ShawGPT
Thanks, glad you liked it! -ShawGPT
Glad it was helpful! -ShawGPT

Schauen wir uns an, wie es mit der glei­chen tech­ni­schen Frage wie zuvor umgeht, näm­lich „Was ist Fat-Tailedness?“

Good question! The fat tail phenomenon represents the size of outlier (extreme) 
events relative to a normal (Gaussian) distribution. In other words, there's a 
greater probability of extreme events occurring compared to a normal 
distribution. -ShawGPT

Obwohl das Modell „Fat Tails“ anders defi­niert, als ich es tun würde, sind die Länge und der Stil der Ant­wort viel bes­ser als das, was wir mit der Assis­ten­ten-API vor RAG gese­hen haben. Dies deu­tet dar­auf hin, dass, wenn wir RAG zu die­sem fein abge­stimm­ten Modell hin­zu­fü­gen wür­den, es deut­lich bes­sere Ant­wor­ten erzeu­gen würde als das, was wir vor­her gese­hen haben.

Was kommt als Nächstes?

Die Erstel­lung eines benut­zer­de­fi­nier­ten KI-Assis­ten­ten ist so ein­fach wie nie zuvor. Hier haben wir einen ein­fa­chen Weg gese­hen, einen KI-Assis­ten­ten über die API von OpenAI’s Assistant zu erstel­len, und wie man ein Modell über ihre Fein­ab­stim­mungs-API fein abstimmt.

Ope­nAI ver­fügt zwar der­zeit über die fort­schritt­lichs­ten Modelle für die Ent­wick­lung der hier bespro­che­nen Art von KI-Assis­ten­ten, aber diese Modelle sind hin­ter ihrer API ver­schlos­sen, was die Mög­lich­kei­ten, mit ihnen zu arbei­ten, einschränkt.

Daher stellt sich natür­lich die Frage, wie wir ähn­li­che Sys­teme mit Open-Source-Lösun­gen ent­wi­ckeln kön­nen. Dies wird in den nächs­ten Arti­keln die­ser Serie behan­delt, in denen ich erör­tern werde, wie man ein Modell mit QLoRA fein abstimmt und einen Chat­bot mit RAG erweitert.

Quelle: medium.com