はじめに
この記事の続きです。
前回は、2B以下のモデルを動かしていましたが、今回はllama.cppを使ってもう少し大きめのモデルを動かしてみたいと思います。
PCスペック
OS : windows
CPU : AMD Ryzen 7 5700U with Radeon Graphics
メモリ : 16GB
この記事でやること
- llama-cpp-pythonを使ってLLMを動かす
インストールしたライブラリ
llama-cpp-pythoが必要です。
pip isntall llama-cpp-python
上手くいかない場合は下記の記事を参考にしてください。
モデルを使うときにエラーが出る場合は、モデルが古かったりするみたいです。
llama-cpp-pythonの使い方
llama-cpp-pythonを使うと量子化されたモデルをCPUでも使えるようになるみたいです。
パラメータ数が大きいモデルをCPUだけでさくさく動かせるようになるようです。
まず、Hugging Faceから使いたいモデルをダウンロードします。
例えば、Phi-3をダウンロードして任意のフォルダに置きます。
今回はmodelsというフォルダの中に入れています。
これで完了です。
読み込みはこのくらいです。簡単ですね。
llm = Llama(
model_path="models/Phi-3-mini-4k-instruct-q4.gguf", # path
n_ctx=1024, # 任意、phi-3-mini-4kってなってるので4096まで?
n_gpu_layers=0 # GPUを使わないので
)
出力を確認する
今回試すモデルは、下記の4つです。InternVLは最近話題になってた(?)ので使ってみました。
(ggufはもしかしたら公式ではないかも・・・?)
- Phi-3-mini-4k-instruct-q4.gguf (3B?)
- phi-4-TQ1_0.gguf (14B?)
- InternVL3-8B-UD-IQ2_XXS.gguf (8B)
- InternVL3-14B-Instruct-UD-IQ2_XXS.gguf (14B?)
プロンプト
purpose = "irisの特徴量とtargetの散布図を可視化する"
prompt_ = f"""
あなたは熟練のデータサイエンティストです。
ユーザーの分析目標とデータの概要をもとに、適切な可視化を提案してください。
# 出力ルール
- 出力は必ず **JSON形式のみ** とする
- JSONのトップレベルキーは "visualizations"
- visualizations はリストで、各要素は以下の形式とする:
{{
"type": "scatter" | "histogram" | "bar" | "box",
"columns": ["カラム1", "カラム2", ...]
}}
- 余分な文章は一切出力しないこと
# 出力例
{{
"visualizations": [
{{"type": "scatter", "x_col": "feature_1", "y_col":"feature_2"}},
{{"type": "histogram", "columns": ["feature_1", "feature_2"]}},
{{"type": "bar", "columns": ["feature_1", "feature_2"]}},
{{"type": "box", "columns": ["feature_1", "feature_2"]}},
]
}}
# 分析目標
- {purpose}
# データの概要
- 行数: {df_size[0]}
- 列数: {df_size[1]}
- int型カラム: {int_columns}
- float型カラム: {float_columns}
- object型カラム: {categorical_columns}
- bool型カラム: {bool_columns}
"""
prompt= [
{"role": "system", "content": "あなたは熟練のデータサイエンティストです。分析目標とデータの概要から分析計画を立ててください"},
{"role": "user", "content": f"{prompt_}"},
]
出力コード
def output(llm, prompt):
output = llm.create_chat_completion(
messages=prompt,
max_tokens=4096,
stop=["<|end|>"],
stream=False,
)
return output
print(output['choices'][0]['message']['content'])
Phi-3-mini-4k-instruct-gguf
読み込み~出力で30秒くらいでした。めちゃ速いですね。
きれいに出力してくれましたが、y_colにはtargetを指定してほしいですね。
{
"visualizations": [
{"type": "scatter", "x_col": "sepal length (cm)", "y_col": "sepal width (cm)"},
{"type": "scatter", "x_col": "petal length (cm)", "y_col": "petal width (cm)"}
]
}
phi-4-TQ1_0.gguf
読み込み~出力まで13分程度でした。
phi-3でそこそこうまくいったので期待してましたが、よくわからない文字列が出力されてしまいました。プロンプトが悪いのか読み込みの設定とかが悪いのか・・・
ilegeLinkId imperfect_tDLinkIdLinkId imperfect_tD_tD_tDilege imperfect imperfect_tDLinkId imperfect imperfect_tD_tD_tD imperfect_tD imperfect_tD_tDLinkIdLinkIdLinkId # 以下繰り返し。
InternVL3-8B-UD-IQ2_XXS.gguf
読み込み~出力まで1分30秒くらいでした。完璧に見えますがリストが閉じられていません。
閉じられていれば完璧でした。プロンプトとかで何とかなるのか・・・?
{
"visualizations": [
{"type": "scatter", "x_col": "sepal length (cm)", "y_col": "sepal width (cm")},
{"type": "scatter", "x_col": "petal length (cm)", "y_col": "petal width (cm)"},
{"type": "scatter", "x_col": "sepal length (cm)", "y_col": "petal length (cm)"},
{"type": "scatter", "x_col": "sepal width (cm)", "y_col": "petal width (cm)"},
{"type": "scatter", "x_col": "sepal length (cm)", "y_col": "target"},
{"type": "scatter", "x_col": "sepal width (cm)", "y_col": "target"},
{"type": "scatter", "x_col": "petal length (cm)", "y_col": "target"},
{"type": "scatter", "x_col": "petal width (cm)", "y_col": "target"}
}
InternVL3-14B-Instruct-UD-IQ2_XXS.gguf
読み込み~出力まで3分くらいでした。
完璧です。8Bのものとはちがってちゃんとリストも閉じられています。
{
"visualizations": [
{"type": "scatter", "x_col": "sepal length (cm)", "y_col": "petal length (cm)"},
{"type": "scatter", "x_col": "sepal width (cm)", "y_col": "petal width (cm)"},
{"type": "scatter", "x_col": "petal length (cm)", "y_col": "petal width (cm)"},
{"type": "scatter", "x_col": "sepal length (cm)", "y_col": "target"},
{"type": "scatter", "x_col": "sepal width (cm)", "y_col": "target"},
{"type": "scatter", "x_col": "petal length (cm)", "y_col": "target"},
{"type": "scatter", "x_col": "petal width (cm)", "y_col": "target"}
]
}
結果
出力としては、InternVL3.5-14Bが一番良かったわけです。ここまでいくにもプロンプトをいろいろ試しているので、小さいモデルを使うときのプロンプトにはかなり気を使わないといけないと感じています。また、前回の記事とoutputの仕方を変えているのでそれも聞いているかもしれません。速度的にはPhi-3くらいでさくさく進められるとうれしい感じはします。
やっとここら辺を触り始めたんですけど、いろいろ試してみようと思います。