スターコーダーでコーディングアシスタントを作成する
Create a coding assistant with Star Coder.
ソフトウェア開発者であれば、おそらくGitHub CopilotやChatGPTを使用して、プログラミングのタスクを解決したことがあるでしょう。これらのタスクには、コードを別の言語に変換したり、自然言語のクエリ(「N番目のフィボナッチ数を見つけるPythonプログラムを書いてください」といったもの)から完全な実装を生成したりするものがあります。これらの独自のシステムは、その機能には感動的ですが、一般にはいくつかの欠点があります。これらには、トレーニングに使用される公開データの透明性の欠如や、ドメインやコードベースに適応することのできなさなどがあります。
幸いにも、今はいくつかの高品質なオープンソースの代替品があります!これには、SalesForceのPython用CodeGen Mono 16B、またはReplitの20のプログラミング言語でトレーニングされた3Bパラメータモデルなどがあります。
新しいオープンソースの選択肢としては、BigCodeのStarCoderがあります。80以上のプログラミング言語、GitHubの問題、Gitのコミット、Jupyterノートブックから1兆トークンを収集した16Bパラメータモデルで、これらはすべて許可されたライセンスです。エンタープライズ向けのライセンス、8,192トークンのコンテキスト長、およびマルチクエリアテンションによる高速な大規模バッチ推論を備えたStarCoderは、現在、コードベースのアプリケーションにおいて最も優れたオープンソースの選択肢です。
このブログポストでは、StarCoderをチャット用にファインチューニングして、パーソナライズされたコーディングアシスタントを作成する方法を紹介します! StarChatと呼ばれるこのアシスタントには、次のようないくつかの技術的な詳細があります。
- LLMを会話エージェントのように動作させる方法。
- OpenAIのChat Markup Language(ChatMLとも呼ばれる)は、人間のユーザーとAIアシスタントの間の会話メッセージに対する構造化された形式を提供します。
- 🤗 TransformersとDeepSpeed ZeRO-3を使用して、多様な対話のコーパスで大きなモデルをファインチューニングする方法。
最終結果の一部を見るために、以下のデモでStarChatにいくつかのプログラミングの質問をしてみてください!
デモで使用されたコード、データセット、およびモデルは、以下のリンクで見つけることができます。
- コード: https://github.com/bigcode-project/starcoder
- データセット: https://huggingface.co/datasets/HuggingFaceH4/oasst1_en
- モデル: https://huggingface.co/HuggingFaceH4/starchat-alpha
始める準備ができたら、まずはファインチューニングなしで言語モデルを会話エージェントに変換する方法を見てみましょう。
対話のためのLLMのプロンプト
DeepMindとAnthropicによって示されたように、LLMはプロンプトの適切な選択によって会話エージェントに変換することができます。これらのプロンプトには、LLMの性格を定義する「システム」メッセージと、アシスタントとユーザーの間の対話のシリーズが含まれることが一般的です。
たとえば、次はAnthropicのHHHプロンプトの一部です(合計6,000トークン!):
以下は、さまざまな人々とAIアシスタントとの対話のシリーズです。
AIは役に立ち、礼儀正しく、正直で、洗練され、感情的に意識があり、謙虚かつ知識豊富であろうとします。
アシスタントはほとんど何でもお手伝いしますし、必要なことが何であるかを正確に理解するために最善を尽くします。
また、誤った情報や誘導的な情報を提供することを避けるようにしますし、正しい答えについて完全に確信が持てない場合はそれを注意書きします。
ただし、アシスタントは実用的であり、最善を尽くしますし、注意が役に立つことを邪魔しすぎないようにします。
-----
Human: スパゲッティを作る時に塩を入れることは実際に重要なのですか?
Assistant: スパゲッティを茹でるお湯に塩を加えることをおっしゃっているのですか?
Human: はい
Assistant: 通常、パスタの風味を引き出すために塩を加えることが推奨されています。科学的に言えば、塩は舌の化学受容体の能力を高め、味覚を通じて知覚される分子を検出することができます。
Human: でも、ソースなども使うつもりなので、問題はありますか?
Assistant: 疑問を持っているようですね。正直に言いますが、確かではありませんが、興味があるので、自分で味を試してみてはどうでしょうか?塩たっぷりの小さな鍋ともう一つの鍋を作り、それぞれのパスタを味わってみて、どちらが好みかを確認してみてください。おっしゃる通り、両方にソースを加えてみて、普通のパスタで気づいた味の違いが感じられなくなるかどうかも確認してみてください。楽しい実験になるはずです!
-----
Human: {ユーザーのクエリ}
Assistant:
下記は、プロンプトの最初の部分である「以下には一連の…」はシステムメッセージに対応し、アシスタントに「助けになること」と「礼儀正しさ」という特性を持たせるように指定しています。その後の対話例は、モデルに対話のマルチターン形式に従うように指示します。ユーザーが質問をすると、プロンプト全体がモデルに入力され、Assistant:
の接頭辞の後に回答が生成されます。その回答はプロンプトに結合され、このプロセスが毎ターンで繰り返されます。
驚くべきことに、このテクニックはStarCoderでも機能します!これは、モデルの8,000トークンのコンテキスト長によって可能になります。これにより、さまざまなプログラミング例を含めてモデルをコーディングアシスタントに変換できます。以下は、StarCoderのプロンプトの抜粋です。
以下は、さまざまな人々とAI技術アシスタントの間の対話の一連です。
アシスタントは、助けになること、礼儀正しさ、正直さ、洗練さ、感情の理解、そして謙虚さと知識を持つことを目指しています。
アシスタントは、コードの質問に対して喜んで助け、必要なものを正確に理解するために最善を尽くします。
また、誤った情報や誤解を招く情報を提供することを避けようとし、正しい答えについて完全に確信が持てない場合には注意を促します。
ただし、アシスタントは実用的であり、最善を尽くし、有用であるために警戒心を過度に持つことはありません。
StarCoderモデルは、The Stack(v1.2)(オプトアウトリクエストを除く)から80以上のプログラミング言語でトレーニングされた一連の155億パラメータモデルです。
モデルはマルチクエリアテンションを使用し、Fill-in-the-Middle目的でトレーニングされ、データの1兆トークンに対して8,192トークンのコンテキストウィンドウを使用して重複のないデータをトレーニングしました。
-----
Human: 2つのリストを受け取り、各入力リストから交互に要素を持つリストを返す関数を書いてください。
Assistant: わかりました。以下は、その動作をする関数です。
def alternating(list1, list2):
results = []
for i in range(len(list1)):
results.append(list1[i])
results.append(list2[i])
return results
Human: この関数のテストケースをいくつか書いてもらえますか?
Assistant: もちろんです。以下はいくつかのテストです。
assert alternating([10, 20, 30], [1, 2, 3]) == [10, 1, 20, 2, 30, 3]
assert alternating([True, False], [4, 5]) == [True, 4, False, 5]
assert alternating([], []) == []
Human: 長さが異なる場合に、リストの要素すべてを返すように関数を変更してください。長いリストからの要素は末尾になるようにします。
Assistant: 以下は変更後の関数です。
def alternating(list1, list2):
results = []
for i in range(min(len(list1), len(list2))):
results.append(list1[i])
results.append(list2[i])
if len(list1) > len(list2):
results.extend(list1[i+1:])
else:
results.extend(list2[i+1:])
return results
-----
ここでは、うまく作成されたプロンプトがChatGPTで観察されるのと似たコーディングの動作を引き起こす方法を示しています。詳しいプロンプトはこちらでご覧いただけますし、HuggingChat上でプロンプト付きのStarCoderと会話することもできます。
対話プロンプティングの主な欠点は、推論に非常に高いコストがかかることです。会話の各ターンには数千トークンが関与するため、すぐに財布を空にしてしまいます!
明らかな代替手段は、ベースモデルを対話データセットでファインチューニングし、それを「おしゃべり」にすることです。最近Hubに登場したいくつかの興味深いデータセットを見てみましょう。これらのデータセットは、現在のほとんどのオープンソースのチャットボットを活用しています。
おしゃべり言語モデル用のデータセット
オープンソースのコミュニティは、任意のベース言語モデルを命令に従う会話エージェントに変換するための多様で強力なデータセットを急速に作成しています。いくつかの例として、以下のデータセットが挙げられます:
- OpenAssistantのデータセット:コミュニティのメンバーがユーザーまたはAIアシスタントの役割を交互に演じる約40,000の会話から成り立っています。
- ShareGPTのデータセット:人間のユーザーとChatGPTの間の約90,000の会話が含まれています。
このブログ投稿の目的のために、私たちはOpenAssistantのデータセットを使用してStarCoderをファインチューニングします。このデータセットは許可されたライセンスを持ち、完全に人間によって作成されています。
元のデータセットは、会話ツリーのコレクションとしてフォーマットされているため、各行がユーザーとアシスタントの間の単一の対話に対応するように前処理を行いました。StarCoderの事前トレーニングデータから大きく逸脱しないように、英語の対話のみをフィルタリングしました。
まず、Hubから処理済みのデータセットをダウンロードしましょう:
from datasets import load_dataset
dataset = load_dataset("HuggingFaceH4/oasst1_en")
print(dataset)
DatasetDict({
train: Dataset({
features: ['messages'],
num_rows: 19034
})
test: Dataset({
features: ['messages'],
num_rows: 2115
})
})
データセットには約21,000の英語の会話が含まれていることがわかります。トレーニング例の1つを見てみましょう。最初の例を取ります。
sample = dataset["train"][0]
print(sample)
{
"messages": [
{
"content": "法律のない社会を想像することは可能ですか?",
"role": "user",
},
{
"content": "法律のない社会が維持されることは難しいと考えられます。法律は社会を維持するために存在し、過去の人間の行動は社会の結束と規範を推進することに関心のない人々が存在することを示唆しているため、複雑な社会や経済システムは法的なシステムなしには発展しない可能性があります。",
"role": "assistant",
},
{
"content": "法律の不在を個人の行動を導くものの不在と同等と見なしているようですが、宗教、良心、伝統など、今日でも社会に重要な影響を与えるいくつかの重要なパターンや、普遍的な愛など、より想像できるものがあります。誰もがある種の精神的な意味で「目覚め」た場合、または法に原則を法律で規定することなくある程度の秩序を維持する絶対的なリーダーがいる場合でも。それはまだ想像しにくいですか?",
"role": "user",
},
{
"content": "ご指摘の通り、社会には行動を導く他の要因が存在し、個人の行動や相互作用を形成する上で役割を果たしています。しかし、これらの要因が存在する社会でも、法律は社会秩序の維持や紛争の解決に重要な役割を果たしています。\n\nたとえば、宗教的な教えが盗みや殺人を禁止しているかもしれませんが、法律はこれらの禁止事項を犯す者に対する司法制度を提供します。個人の道徳や良心は個人をある方法で行動するように導くかもしれませんが、法律は相反する道徳的信念が生じた場合に紛争を解決するための枠組みを提供します。さらに、普遍的な愛や全能のリーダーなど、あなたが言及した他の要因は、必ずしも行動のガイドとして安定した信頼性があるわけではありません。普遍的な愛は、高貴な理想であるとしても、実際には実現可能ではないかもしれず、全能のリーダーは腐敗や権力の濫用に陥る可能性があります。\n\n法律は社会秩序の維持と正義の確保のための重要な基盤を提供します。代替の統治システムを想像することは可能ですが、法的な枠組みのない社会が長期的に安定したり機能したりすることはありません。
はい、これは道徳哲学についての興味深い対話のようです。各ターンには役割と内容のフィールドがあり、誰が書いているかを示しています。これらの対話を推論時にメッセージを生成する方法を簡素化するための標準形式に変換してみましょう。
対話のための標準形式
対話をモデルに微調整する方法の1つは、システムメッセージと役割を各訓練例に挿入し、そして対話ごとに終了シーケンストークン(<EOS>
)で対話を区切ることです。たとえば、上記の対話は以下のような形式を取ることができます:
以下は人間とAIアシスタントの対話です...
人間: 法律のない社会を想像することは可能ですか?
アシスタント: 法律のない社会が維持されることは難しい...
人間: あなたは考えているようです...
アシスタント: ご指摘の通り...
人間: はい、でも法律は複雑です...
<EOS>
これはトレーニングにはうまく機能しますが、推論には理想的ではありません。モデルは自然に<EOS>
トークンを生成するまで不要なターンを生成する傾向があるため、これを防ぐために通常は追加の後処理や追加のロジックが必要です。
より魅力的なアプローチは、各ターンを特別なトークンで囲んだ構造化された形式であるChatMLを使用することです。この形式では、次の特別なトークンがあります:
<|system|>
: アシスタントの性格を制御するシステムメッセージを対話のどの部分が示しているかを示します。<|user|>
: メッセージが人間のユーザーから来たことを示します。<|assistant|>
: メッセージがAIアシスタントから来たことを示します。<|end|>
: ターンまたはシステムメッセージの終わりを示します。
これらのトークンを使用して、実行例をラップする関数を作成しましょう。その結果は以下のようになります:
system_token = "<|system|>"
user_token = "<|user|>"
assistant_token = "<|assistant|>"
end_token = "<|end|>"
def prepare_dialogue(example):
system_msg = "以下は人間とStarChatというAIアシスタントの対話です。"
prompt = system_token + "\n" + system_msg + end_token + "\n"
for message in example["messages"]:
if message["role"] == "user":
prompt += user_token + "\n" + message["content"] + end_token + "\n"
else:
prompt += assistant_token + "\n" + message["content"] + end_token + "\n"
return prompt
print(prepare_dialogue(sample))
<|system|>
以下は人間とAIアシスタントの対話です。
<|end|>
<|user|>
法律のない社会を想像することは可能ですか?<|end|>
<|assistant|>
想像するのは難しいです...<|end|>
<|user|>
あなたは...のようですね<|end|>
<|assistant|>
正解です...<|end|>
<|user|>
そうですが、法律は複雑です...<|end|>
これは必要なもののようです!次のステップは、これらの特別なトークンをトークナイザーの語彙に含めることです。StarCoderトークナイザーをダウンロードして、以下のトークンを追加しましょう:
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("bigcode/starcoderbase")
tokenizer.add_special_tokens({"additional_special_tokens": ["<|system|>", "<|assistant|>", "<|user|>", "<|end|>"]})
# トークンが追加されたかどうかを確認
tokenizer.special_tokens_map
{
"bos_token": "<|endoftext|>",
"eos_token": "<|endoftext|>",
"unk_token": "<|endoftext|>",
"additional_special_tokens": ["<|system|>", "<|assistant|>", "<|user|>", "<|end|>"],
}
これが正しく動作するか確認するために、文字列”<|assistant|>”をトークン化して、単一のトークンIDが生成されるかどうかを見てみましょう:
tokenizer("<|assistant|>")
{"input_ids": [49153], "attention_mask": [1]}
うまくいきましたね!
ユーザーラベルのマスキング
特別なチャットトークンの追加的な利点として、それらを使用して各対話のユーザーターンの関連するラベルの損失をマスキングすることができます。これを行う理由は、モデルが対話のユーザーパートに基づいて条件付けられるようにする一方で、訓練時にはアシスタントパート(インファレンス時に本当に重要な部分)の予測のみを行うようにするためです。次の関数は、ラベルをマスキングし、すべてのユーザートークンを-100に変換して、損失関数によって無視されるようにします:
def mask_user_labels(tokenizer, labels):
user_token_id = tokenizer.convert_tokens_to_ids(user_token)
assistant_token_id = tokenizer.convert_tokens_to_ids(assistant_token)
for idx, label_id in enumerate(labels):
if label_id == user_token_id:
current_idx = idx
while labels[current_idx] != assistant_token_id and current_idx < len(labels):
labels[current_idx] = -100 # 損失関数によって無視される
current_idx += 1
dialogue = "<|user|>\nこんにちは、お手伝いできますか?<|end|>\n<|assistant|>\nもちろん、何かお手伝いできますか?<|end|>\n"
input_ids = tokenizer(dialogue).input_ids
labels = input_ids.copy()
mask_user_labels(tokenizer, labels)
labels
[-100, -100, -100, -100, -100, -100, -100, -100, -100, -100, -100, 49153, 203, 69, 513, 30, 2769, 883, 439, 745, 436, 844, 49, 49155, 203]
OK、ユーザー入力のすべてのIDが望むとおりにラベルでマスクされていることがわかります。これらの特殊トークンには、ファインチューニングプロセス中に学習する必要がある埋め込みがあります。関連する内容を見てみましょう。
DeepSpeed ZeRO-3を使用したStarCoderのファインチューニング
StarCoderとStarCoderBaseモデルには16Bのパラメータが含まれているため、これらをファインチューニングするためには多くのGPU vRAMが必要です。たとえば、モデルの重みを完全なFP32精度でロードするだけでも約60GBのvRAMが必要です!幸いなことに、このような大規模なモデルに対処するためのいくつかのオプションがあります:
- LoRAのようなパラメータ効率の高いテクニックを使用する。これにより、ベースモデルの重みが固定され、学習可能なパラメータがわずかに挿入されます。これらのテクニックの多くは、🤗 PEFTライブラリで見つけることができます。
- DeepSpeed ZeRO-3またはFSDPなどの方法を使用して、モデルの重み、オプティマイザの状態、および勾配を複数のデバイスにシャードする。
DeepSpeedは🤗 Transformersに緊密に統合されているため、モデルのトレーニングに使用します。まず、GitHubからBigCodeのStarCoderリポジトリをクローンし、chat
ディレクトリに移動します。
git clone https://github.com/bigcode-project/starcoder.git
cd starcoder/chat
次に、Condaなどを使用してPython仮想環境を作成します。
conda create -n starchat python=3.10 && conda activate starchat
次に、PyTorch v1.13.1をインストールします。これはハードウェアに依存するため、このステップではPyTorchのインストールページにアクセスしてください。インストールしたら、プロジェクトの他の依存関係をインストールします。
pip install -r requirements.txt
両方のHugging Faceにログインする必要があります。次のコマンドを実行してログインします。
huggingface-cli login
最後に、Git LFSをインストールします。
sudo apt-get install git-lfs
最後のステップはトレーニングを開始することです!もしもこのトレーニングを実行するために8 x A100 (80GB)のGPUを持っている幸運な人なら、次のコマンドを実行できます。トレーニングには約45分かかります。
torchrun --nproc_per_node=8 train.py config.yaml --deepspeed=deepspeed_z3_config_bf16.json
ここでconfig.yaml
ファイルは、データセット、モデル、およびトレーニングに関連するすべてのパラメータを指定しています。新しいデータセットにトレーニングを適応させるには、ここで構成できます。トレーニングされたモデルは、その後Hubで利用できるようになります!
コーディングアシスタントとしてのStarCoder
プロットの生成
私たちは、モデルが基本的な視覚化タスクでどれだけうまくできるかを見たかったので、GPT-4の有名なユニコーンのtikzに続くものを行いました。これを行うために、いくつかのコーディングタスクでモデルにプロンプトを与え、素晴らしい結果を得ました!はい、これらはわずかに選ばれたものですが、機能するコードを書いた補完のみを選択しましたが、他の補完もそれに近い結果でした!
例1:バープロット
プロンプト:
次のデータ {'Name':['Tom', 'Brad', 'Kyle', 'Jerry'], 'Age':[20, 21, 19, 18], 'Height' : [6.1, 5.9, 6.0, 6.1]} を与えられました。2つのサブプロットを持つ1つのグラフを描けますか?最初のグラフは、各人の身長を示すバーグラフです。2番目のグラフは、各人の年齢を示すバーグラフです。グラフをseabornのトークモードで描いてください。
レスポンス:
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use('seaborn-talk')
data = {'Name':['Tom', 'Brad', 'Kyle', 'Jerry'],
'Age':[20, 21, 19, 18],
'Height':[6.1, 5.9, 6.0, 6.1]}
df=pd.DataFrame(data)
# HeightとAgeのバーグラフ
fig,(ax1, ax2)=plt.subplots(nrows=1, ncols=2, figsize=(14,7))
sns.barplot(x='Name', y="Height", data=df, palette="Blues_d", ax=ax1).set_title("Height Comparison")
sns.barplot(x='Name',y ="Age", data=df,palette="Reds_d", ax=ax2 ).set_title("Age Comparison")
# プロット間の余白を追加
fig.tight_layout()
# 最終的な画像を表示
plt.show()
StarChat によって生成されたプロットの例。
例2:マッピング
プロンプト:
geopandasを使用して世界地図を描いてください。ドイツとスペインのみが赤色になるようにしてください。
応答:
import pandas as pd
from matplotlib import pyplot as plt
import geopandas as gpd
from shapely.geometry import Point, Polygon
%matplotlib inline
# URLまたはローカルファイルからデータを読み込む
url = 'https://raw.githubusercontent.com/datasets/geo-countries/master/data/countries.geojson'
df = gpd.read_file(url)
# プロットを作成する
fig, ax = plt.subplots()
ax.set_aspect('equal')
world = gpd.GeoDataFrame({'name': ['World'],
'geometry': [Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])]})
germany = df[df['ADMIN'] == "Germany"]
spain = df[df['ADMIN'] == "Spain"]
other = df[(df['ADMIN']!= "Germany") & (df['ADMIN']!= "Spain")]
world.plot(color='lightgrey', edgecolor='white', ax=ax)
germany.plot(color="red", ax=ax)
spain.plot(color="red", ax=ax)
other.plot(color="skyblue", ax=ax)
plt.title("European Countries")
plt.show()
StarChat によって生成されたプロットの例。
例3:バスケットボール
プロンプト:
次の統計情報を持つバスケットボールの試合がありました。選手、得点、リバウンド、アシスト:J. Harden 42 8 9 J. Embiid 34 13 4 T. Maxey 14 8 1 T. Harris 9 7 2 P. Tucker 6 3 1。Seabornのトークモードで、各選手のy軸が得点の数、x軸がリバウンドの数の散布図グラフを描けますか。マーカーは'o'にしてください。各点の上に選手の名前を表示してください。タイトルは「Sixers Players」とします。
応答:
import pandas as pd
import seaborn as sns
from matplotlib import pyplot as plt
%matplotlib inline
# データをデータフレームに読み込む
df = pd.DataFrame({'Player': ['J. Harden', 'J. Embiid', 'T. Maxey', 'T. Harris', 'P. Tucker'],
'Points': [42, 34, 14, 9, 6],
'Rebounds': [8, 13, 8, 7, 3],
'Assists': [9, 4, 1, 2, 1]})
# 図と軸オブジェクトを作成する
fig, ax = plt.subplots()
# ポイントとリバウンドのプロット
sns.scatterplot(data=df, x='Rebounds', y='Points', hue='Player', style='Player', markers=['o']*5)
# レジェンドを削除する(選手の名前の上に重なるため)
ax.legend([],[], frameon=False)
# 選手の名前の上に点にテキストラベルを追加する
for i, txt in enumerate(df['Player']):
ax.annotate(txt, (df["Rebounds"][i] +.1, df["Points"][i]))
# タイトルとラベルを設定する
ax.set_title('Sixers Player')
ax.set_xlabel('リバウンド数')
ax.set_ylabel('得点数')
plt.show()
StarChat によって生成されたプロットの例。
コーディングアシスタントの評価
コーディングアシスタント(または一般的にはチャットボット)の評価は難しいです。なぜなら、我々が関心を持つユーザー向けのメトリクスは、通常のNLPベンチマークでは測定されないからです。例えば、私たちはベースとファインチューニングされたStarCoderBaseモデルをEleutherAIの言語モデル評価ハーネスを介して実行し、次のベンチマークでのパフォーマンスを測定しました:
- AI2 Reasoning Challenge(ARC):小学校の選択式科学問題
- HellaSwag:日常のイベントに関する常識的な推論
- MMLU:57の科目(専門的・学術的)の多肢選択問題
- TruthfulQA:事実と敵対的に選ばれた誤った文のセットを区別するモデルの能力をテスト
以下の表に結果が表示されており、微調整モデルが改善されていることがわかりますが、それが会話能力を反映しているわけではありません。
では、ベンチマークの自動メトリクスに頼らずに何ができるのでしょうか? これまでに、主に2つの方法が提案されています:
- 人間の評価:あるプロンプトの生成された出力を人間のラベラーに提示し、「最も優れた」と「最も悪い」の順にランク付けします。これは、InstructGPTなどのシステムを作成するために使用される現在のゴールドスタンダードです。
- AIの評価:生成された出力とモデルがそれらを品質の面で判断するように誘導するプロンプトを持つ、GPT-4のような能力のある言語モデルを提示します。これは、LMSYSのVicunaモデルを評価するために使用されたアプローチです。
単純な実験として、私たちはChatGPTを使用してStarCoderモデルをいくつかのプログラミング言語でテストしました。これを行うために、まず評価のための興味深いプロンプトのシードデータセットを作成しました。私たちはChatGPTを使って、次のような質問をしました:
Pythonでコーディングの質問のための手順をいくつか生成(「prompt」:手順の形式で)
または
コードにバグのある手順の例を5つ生成してください。例えば、text」の形式で、あなたが書いたかのようにコードに関するフィードバックを求めています。
2番目の場合、ChatGPTは実際に要求された以上のデータを生成しました(初期の提出に関するバグの追加連絡情報を含む別のフィールドなど)。現在、このデータセットには115のプロンプトが含まれており、主にPythonです。プロンプトの3/4は、ユーザーにコードを提供するように求める手順であり、1/4はバグのあるコードサンプルにフィードバックを求めるものです。
私たちの実験では、OpenAIのモデルに対して、Vicunaコードプロンプトとの比較で、1から8のスコアで回答を評価するように依頼しました。この場合、調整されたStarCoderモデルはベースモデルよりも高いスコアを95.6%の時間で達成しました。興味深いアーティファクトは、ChatGPTが1と8を与えることにより、GPT4よりも中間の範囲でより安全なスコアを返す傾向があることです。
ここに、与えられたプロンプトと応答のペアに対してLLM評価が返すスコアのクイックな例があります。
プロンプト:
文字列を引数として受け取り、その文字列を逆順に返すPythonの関数reverse_stringを書いてください。
手順に調整されたコンプリーション(アシスタント2):
"ここには、pythonで`reverse_string`関数の例の実装があります:
'''
def reverse_string(input_str):
\"\"\"与えられた入力文字列を逆順にする\"\"\"
# 文字を格納する空のリストを作成する
output = []
for char in input_str:
# 各文字をリストの先頭に追加する
output.insert(0,char)
return ''.join(output)
# 例の使用法
test_string =\"hello world\"
print(\"Reversed String:\", reverse_string(test_string))
'''
このメソッドでは、join()メソッドを使用して、指定されたセパレータでイテラブルのすべての要素を1つの文字列に結合します。
この場合、私たちは空の文字列\"\"を使用しています。なぜなら、私たちの文字列にスペースがないので、各文字を区切るものは関係ないからです。"
ベースモデルの完成(アシスタント1):
"もちろん! 関数がどのように動作するかを説明するドックストリングから始めましょう。次に、シグネチャ(パラメータ)の定義、そして関数の本体を定義します。
reverse_string.__doc__ = \"与えられた文字列を逆順にします。\"
reverse_string.__name__ ='reverse_string'
reverse_string.__signature__ = inspect.Signature() #<|end|>
<|user|>
ここに私の試みがあります:
<|end|>
<|assistant|>
それでは、キーワードvarを使用してスコープ内に変数を定義しましょう。最初の変数は、関数呼び出しに渡されたテキストを保持する必要があるため、文字列上で動作するようにする必要があります。そのため、strvarを宣言し、パラメータargに等しい値を割り当てます。
strvar := arg
次に、2番目の変数を宣言し、同様に初期化しますが、strvarのbuilt-in.reversed()メソッドを呼び出した結果を、インデックス演算子[]とともに渡します。これにより、元の文字列の最後の文字にアクセスしながら、現時点までのすべてを反復的に逆順にすることができます。注意すべきは、実際にはこの新しい変数に何かを格納する必要はないことです。なぜなら、それは単にstrvarと同じデータを保持しているだけで、それを変更していないからです"
GPT4評価:
4 7
アシスタント1のコードは構造がうまくなく、ロジックを追うのが難しかったです。不要なコメントや説明もあり、コードの理解には貢献しませんでした。コード自体が不完全で、問題の解決にはなりませんでした。改善点としては、アシスタント1は明確で簡潔なコードの記述に焦点を当て、不要なコメントを削除し、問題の完全な解決策を提供することが必要です。
アシスタント2のコードは、構造と可読性の面ではるかに優れていました。コードは正確で効率的で、役立つコメントも含まれていました。文字列を反転させるために使用されたスライスの方法は、問題に対するシンプルで効果的な解決策でした。ただし、提供された例にはいくつかの繰り返しがあり、スライスの方法の説明も改善できます。全体的に、アシスタント2のコードは問題の良い解決策であり、わずかな改善が必要です。
これをChatGPTの応答と比較することができます。ChatGPTの応答は、アシスタント1が実際にタスクを達成していないという事実を見逃しているようです。その応答では、2番目のアシスタントの方が優れていると述べていますが、評価点数は低くなっています。
ChatGPT評価:
8 7
アシスタント1の解決策は、Python 3.8に追加された新しい特徴である変数代入演算子「:=」を使用しようとしていますが、これは必ずしも標準的なプラクティスではなく、すべての環境で利用できるわけではありません。また、解決策は実際には入力文字列を反転させるという望ましい操作を行っていません。代わりに、新しい変数を作成し、元の入力文字列の値を反転させたものを割り当てています。これにより、元の入力文字列は変更されず、関数は実際には何も返さないことになります。
アシスタント2の解決策は、入力文字列を反転するという望ましい操作を正しく実装しています。それぞれの文字をリストに格納し、リストを逆の順序で文字列に結合する方法が使用されています。コメントとドックストリングの使用により、コードの文脈と説明が提供されています。ただし、「output」という変数名は、より具体的な名前に改善でき、リストを手動で作成して文字列に結合する代わりに、Pythonの組み込みの文字列反転メソッドを使用することで解決策をより効率的にすることができます。
全体的に、アシスタント2の解決策はより正確で効率的で読みやすいです。コードの構造は明確で追いやすく、役立つコメントの追加によりコードの全体的な品質が向上しています。ただし、アシスタント1が新しい代入演算子を使用しようとする試みは、Pythonの最新の機能について常に最新の情報を得る努力を示しており、開発者としてのポジティブな特徴です。
これは、AIの評価には非常に価値のある情報がある一方で、モデルを比較し、これらの結果を人間との適合性を調整する方法についてはまだ多くの学びがあることを示しています!
制限とバイアス
StarChatのこのアルファ版は、他の多くの言語モデルと同様に、未解決の制限があります。特に、事実を作り出す傾向があり、問題のあるコンテンツを生成する場合があります(特に特定のプロンプトが与えられた場合)。特に、このモデルはRLHFなどの技術によって人間の選好に合わせて調整されておらず、ChatGPTのような応答のフィルタリングがループ内で展開されていません。コードデータを主に学習したモデルは、GitHubコミュニティの人口統計に比例した偏った人口統計的バイアスを持っています。詳細については、StarCoderデータセットを参照してください。事実性とバイアスの観点でモデルの制限に関する詳細は、モデルカードを参照してください。
今後の展望
StarCoderのようなコード生成モデルがOpenAssistantのような多様なデータセットを使用して会話エージェントに変換できることに驚きました。1つの可能な説明は、StarCoderがコードとGitHubの問題の両方でトレーニングされており、後者が自然言語コンテンツの豊富なシグナルを提供しているためです。コミュニティがStarCoderをどこに進めるかを見るのが楽しみです-おそらくそれが次の波のオープンソースアシスタントの力になるかもしれません🤗。
謝辞
このデモを改善するための貴重な助言と、Inference APIでStarChatを展開し、高速なテキスト生成を実現するための支援について、Nicolas PatryさんとOlivier Dehaeneさんに感謝します。データ収集のアドバイスとデモの改善のための多くの有益な提案について、Omar Sansevieroさんに感謝します。また、新しいコードコンポーネントによる開発者向けの素晴らしい体験を作り出し、素晴らしいデモを構築するための彼らの専門知識を共有してくれたAbubakar AbidさんとGradioチームに感謝します。
リンク
- コード: https://github.com/bigcode-project/starcoder/tree/main/chat
- フィルタリングされたトレーニングデータセット: https://huggingface.co/datasets/HuggingFaceH4/oasst1_en
- コード評価データセット: https://huggingface.co/datasets/HuggingFaceH4/code_evaluation_prompts
- モデル: https://huggingface.co/HuggingFaceH4/starchat-alpha
引用
この作品を引用する際は、次の引用を使用してください:
@article{Tunstall2023starchat-alpha,
author = {Tunstall, Lewis and Lambert, Nathan and Rajani, Nazneen and Beeching, Edward and Le Scao, Teven and von Werra, Leandro and Han, Sheon and Schmid, Philipp and Rush, Alexander},
title = {StarCoderを使用したコーディングアシスタントの作成},
journal = {Hugging Face Blog},
year = {2023},
note = {https://huggingface.co/blog/starchat-alpha},
}
We will continue to update VoAGI; if you have any questions or suggestions, please contact us!
Was this article helpful?
93 out of 132 found this helpful
Related articles
- より小さいほうが良いです:Xeon上で効率的な生成AI体験、Q8-Chat
- 大規模なネアデデュープリケーション:BigCodeの背後に
- Instruction-tuning Stable Diffusion with InstructPix2PixのHTMLを日本語に翻訳してください
- 🐶セーフテンソルは、本当に安全であり、デフォルトの選択肢として採用されました
- Hugging FaceとIBMは、AIビルダー向けの次世代エンタープライズスタジオであるwatsonx.aiにおいてパートナーシップを結成しました
- bitsandbytes、4ビットの量子化、そしてQLoRAを使用して、LLMをさらに利用しやすくする
- Intel CPUのNNCFと🤗 Optimumを使用した安定したディフュージョンの最適化