MacローカルにLlama3を入れてチャットするPythonコード

  • このエントリーをはてなブックマークに追加

 ChatGPTに代表されるように、世間ではLLMブームの最中です。ここでは課金が不要でローカル環境にもインストール可能なMeta社のLlamaをMacbookに入れる方法を紹介します。そして、PythonからLlamaを起動してチャットするコードも紹介します。

こんにちは。wat(@watlablog)です。ここでは流行りのLLMをローカルPC上で動かすためLlamaをmacOSに入れてみます

はじめに

LLMとは?

 LLMLarge Language Model)は、大規模なテキストデータをもとに学習された自然言語処理モデルです。人間の指示に応じて文章を生成したり、要約や翻訳、プログラミング支援など幅広いタスクをこなす能力を持ちます。

 代表例には、OpenAIの「GPT」シリーズや、Anthropicの「Claude」、Meta社が開発した「Llama」シリーズなどがあります。2025年現在のLLMの進化は本当に驚くレベルになっており、自然言語で違和感のないやり取りが可能です。プログラムの分野ではアイデアのブレインストーミングのみならず、コードの生成やエラー解消まで実際に役に立つレベルになっています。

Advertisements

 普段のPythonアプリケーションにLLMを導入することができればユーザーからの自然言語による処理を組み込むことができるので、従来のプログラミングの枠を一歩越えることができそうです。
 

LLMをローカルで動かすモチベーション

 今回筆者はLLMをローカル環境で動かしてみたくなってきました。その理由は無料でPythonアプリケーションと連携してみたいからです。多くの商用LLM(ChatGPTなど)は、クラウド上で動作し、利用にはAPIキーの取得や月額課金を必要とするケースが一般的です。
 一方Llamaのようなオープンウェイト(モデルの重みが公開されている)なLLMは、適切な条件下でローカル環境にも導入でき、無料で推論を行うことが可能です。

 特にアプリを一般にリリースする場合はユーザーがどれくらいのトークンを使用するか初期的に予測することが困難です。LLMの月額課金料をユーザーに追加することになると、ユーザーがアプリを導入する敷居を高めてしまうことにもなりかねません。
 またアプリ開発中に有料版のLLMを使っていると、テストの度に0.1$...0.2$...と増えていきます。テストの量がそんなに多くない場合は問題ないですが、何度もバグフィックスのためにお金がかかるのはムナシイものです。とりあえず精度は二の次に、自然言語でやり取りできるアプリをつくってみたいというモチベーションで筆者はLlamaを選択しました。

WATLABブログではAIカテゴリを持っていますが、流行りのLLMコンテンツがなかったので書いてみたかったというのもあります!

環境

 今回は筆者のM3 Macbook AirにLlama3を導入する方法を紹介します。

Mac OS macOS Sonoma 14.3
チップ Apple M3
CPU 1.4[GHz]
メモリ 16[GB]

Llamaモデルのダウンロード

Hugging Face

 Hugging Faceという機械学習・自然言語処理(NLP)向けのオープンプラットフォームおよびコミュニティがあります。今回筆者がダウンロードするのは容量が非常に軽量で小規模な開発やテストにちょうど良い meta-llama-3-8b-instruct.Q4_K_M.ggufモデルです。

 以下のURLにそのモデルがあるので、ダウンロードしましょう。5GB弱あるので少し時間がかかると思います。

https://huggingface.co/NoelJacob/Meta-Llama-3-8B-Instruct-Q4_K_M-GGUF/blob/main/meta-llama-3-8b-instruct.Q4_K_M.gguf

項目 内容
モデル名 LLaMA 3 8B Instruct
開発元 Meta
パラメータ数 約80億(8B)
モデル目的 指示応答・チャット向け(Instruct)
量子化形式 Q4_K_M(4bit量子化で精度と速度・容量のバランス型)
推論エンジン llama.cpp(または llama-cpp-python)
保存形式 GGUF(量子化モデル用の高速・軽量なフォーマット)
メモリ使用量の目安 約5GB前後(Q4量子化時)
想定用途 ローカルでのチャットボット・コード補完・記事生成など
オフライン利用 可能(完全ローカルで使用可)

 モデルがダウンロードできたら、そのモデルを任意のディレクトリにおきます。

PythonからLlamaを使う

pip installコマンド

 PythonからLlamaを使うために、 llama-cpp-pythonというライブラリを pip installしましょう。

 引数が沢山ついていますが、意味を下表に示します。

引数 説明
--verbose 詳細なログを表示。ビルドやダウンロード中の進行状況・エラーを確認しやすくなる
--force-reinstall 既にインストール済みでも強制的に再インストールする(設定変更時に便利)
--no-cache-dir pipのキャッシュを使わない。古いバイナリや一時ファイルの影響を避けるため
--config-settings=cmake.build-type=Release CMakeのビルド設定を指定:ここでは最適化付きの「Releaseビルド」
--config-settings=cmake.define.GGML_METAL=ON CMakeのオプションを追加:AppleのMetal(GPU)を有効化する設定(macOS専用)

GPUが使えるかどうかを確認する

 自分のPCがGPUを使えるかどうかを確認してみましょう。わざわざカタログを見なくても、Python使いなら次のPythonコードで確認可能です。

MacのGPUスペックを確認する

 より詳細に使っているMac端末のGPU情報を知りたい場合は、次の操作で確認可能です。

Appleアイコン→このMacについて→詳細情報→システムレポート→グラフィックス/ディスプレイ

テキストを入力して回答を得るPythonコード

コード全文

 それでは早速Llamaに質問を投げかけて回答をもらいましょう。次のコードはテキスト(プロンプト)で「シンギュラリティはいつ来ると思う?」と投げかけてみたものです。 llmでインスタンスを作成していますが、ここに最大コンテキスト長 n_ctxCPUコア最大並列数 n_threadsGPUで処理する層数 n_gpu_layers出力ウィンドウへの詳細表示 verboseを設定します。

コンテキストとトークン

 最大コンテキスト長とは、このモデルで扱う最大のトークン数を意味します。入力テキストは必ずしも1文字単位でトークンが表現されるのではなく、LLMが扱う意味のある塊(トークン)で考える必要があります。プログラムを実行すると出力ウィンドウに llama.context_length u32 = 8192と表示されますが、この8192が先ほどダウンロードしたモデルの最大コンテキスト長です。トークン数は出力ウィンドウにも出ていますが、トークン数を計算するための tiktokenというライブラリもあるそうです。

 色々な用語がでてきていますが、この n_ctx一回の推論で処理できるトークン数の合計(入力+出力)と覚えておけば良いと思います。

GPUで処理する層数

  n_gpu_layersはこのモデルがどの層までをGPUで処理するかを決める設定です。GPUで処理できない部分はCPUで処理されます。全部CPUで処理する場合は0全部GPUで処理する場合は-1です。

最大トークン数と温度

  responseでは最大トークン数 max_tokensを設定します。これは今回の回答で出力する最大のトークン数を意味しており、この値が少ないと回答が途中で切れてしまったりします。

 一方 temperatureは直訳すると温度という意味ですが、LLMが回答するときの多様性を表現するパラメータです。筆者自身もどう表現した方が良いかよくわからなかったので、ChatGPTに聞いてみたら以下の分類がされました。面白いので表にまとめておきます。

目的 意味 例えるなら 推奨温度
正確で一貫した回答が欲しい 確定的・論理的な出力 教科書を読むロボット 0.0〜0.3
自然な会話をしたい バランスの取れた多様性 冷静な人間 0.7(デフォルト)
面白い文章を出したい ひらめきや創造性がある ちょっと自由な人 1.0〜1.3
詩・創作・アイデア出し ランダム性が強く、予測不能 酔っぱらい or ポエマー 1.5以上

実行結果:そのまま実行

 コード実行結果から文章部分を日本語に訳し、以下に示します(回答は英語で返ってきました)。

ちょっと興奮気味、ジョークもかませつつ会話をしてくる性格みたいですね。

実行結果:GPUの比率を高めてみる

  n_gpu_layers=-1(全層数GPU)にしたところ、以下の回答が返ってきました。

長文!出典まで書いてあるけど、ちょっと調べても出てこないので存在しない論文が多そうですね。まあこんなもんでしょうか。

連続した会話(チャット)をさせるPythonコード

コード全文

 質問と回答を一回だけではなく、チャットのように何回も繰り返してみましょう。Llama(他のLLMも?)の仕様的に通常はテキストを一回渡して回答するだけで、複数の会話を記憶する能力はないようです。そのため記憶をどうさせるかという工夫が必要です。

 次のコードはLlamaとチャットするためのPythonコードです。

記憶を引き継ぐ方法

 Llamaに渡すプロンプトを役割(role)と内容(content)で構成し、辞書型として構成します。そして質問と回答をすべて .appendで追加し、毎回の質問で連結されたプロンプト conversation_historyを投げます。
  conversation_historyの中身は下図のような形式です。

プロンプトの追加

 そして最初のコードとの違いは回答を得る時に response = llm.create_chat_completion()を使う部分にもあります。これはユーザーとアシスタント(LLM)のメッセージ列からチャット形式の応答を得るためのものです。詳細は以下のGitHubをご確認ください。
https://github.com/abetlen/llama-cpp-python

日本語への翻訳

 Llamaは日本語で質問しても、「日本語でお願いします」と指定しても回答は英語で返ってくることがありました。そのため deep_translatorから GoogleTranslator importして翻訳する機能を追加しています。インターネットを使う必要があるので、オフライン用途には向きませんが、今回は止むなし。

 日本語で返ってくる場合もあるので、 langdetectというライブラリを使って日本語かどうかを判定して日本語ならそのまま出力、日本語以外なら翻訳するという処理を追加しました。

実行結果:チャット例

 以下にコードの実行例を示します。

  • 最初の質問と回答

 Llama3のパラメータ数について質問し、各層のサイズを回答しているので真偽はともかくまともな回答になっています。

  • 2回目の質問と回答

 曖昧に「どれくらいのコンピュータ」という質問をしたのに対して、適切にハードウェアのリソースについての文脈だと解釈してくれました。

  • 3回目の質問と回答

 そして3回目の質問で2つ前の質問内容を聞いてみたところ、ちゃんと当てています。これで conversation_historyが適切に働き、記憶が保持されていることを確認できましたね。

まとめ

 この記事ではローカルLLMのLlama3をMacbookに入れてPythonで使う方法について説明しました。数行のコードでチャット形式の質疑応答ができるのには驚きました。
 ただし、ここで紹介しているチャットができるコードは最大コンテキスト長に注意が必要です。全体のトークン(入力+出力)が最大値を超えると古いものから忘れてしまうので、たくさんチャットしたい場合はもっと余裕のあるモデルを選定するといったことが必要になると思います。

 とはいえPythonプログラミングで自然言語が扱えるとユーザーからの入力の幅が広がります。リアルタイムに最新技術にキャッチアップするのはなかなか厳しいですが、今後はAIエージェントやMCPにも触れられると良いなと思いました。

ローカルLLMを使ってチャットコードを書くことができました!
Xでも関連情報をつぶやいているので、wat(@watlablog)のフォローお待ちしています!

  • このエントリーをはてなブックマークに追加

SNSでもご購読できます。

コメントを残す

*