メインコンテンツへスキップ
見出し画像

Llama.cpp で Llama 2 を試す

    「Llama.cpp」で「Llama 2」を試したので、まとめました。

    ・macOS 13.4.1
    ・Windows 11

    前回

    1. Llama.cpp

    「Llama.cpp」はC言語で記述されたLLMのランタイムです。「Llama.cpp」の主な目標は、MacBookで4bit量子化を使用してLLAMAモデルを実行することです。
    特徴は、次のとおりです。

    ・依存関係のないプレーンなC/C++実装
    ・Appleシリコンファースト
     (ARM NEON、Accelerate、Metalを介して最適化)
    ・x86アーキテクチャのAVX、AVX2、AVX512のサポート
    ・Mixed F16/F32精度
    ・4bit、5bit、8bit量子化サポート
    ・BLASでOpenBLAS/Apple BLAS/ARM Performance Lib/ATLAS/BLIS/Intel MKL/NVHPC/ACML/SCSL/SGIMATHなどをサポート
    ・cuBLASとCLBlastのサポート

    サポートされているプラットフォームは、つぎおとおりです。

    ・Mac OS
    ・Linux
    ・Windows (CMake経由)
    ・Docker

    2. LLama 2 のモデル一覧

    「Llama.cpp」を利用するには、「Llama 2」モデルをGGML形式に変換する必要があります。HuggingFaceには、変換済みのモデルが公開されています。

    ・TheBloke/Llama-2-70B-GGML
    ・
    TheBloke/Llama-2-70B-Chat-GGML
    ・TheBloke/Llama-2-13B-GGML
    ・
    TheBloke/Llama-2-13B-chat-GGML
    ・
    TheBloke/Llama-2-7B-GGML
    ・
    TheBloke/Llama-2-7B-Chat-GGML

    今回は、「TheBloke/Llama-2-7B-Chat-GGML」の「Files and versions」タブを選択し、4bit量子化版「llama-2-7b-chat.ggmlv3.q4_K_M.bin」をダウンロードします。

    【注意】
    最新の「Llama.cpp」では、ファイルフォーマットが「GGML」 (*.bin)から「GGUF」 (*.gguf) に変更になりました。

    画像

    推奨は、「Q4_K_M」「Q5_K_M」「Q5_K_S」です。

    ・必要な最大RAM
    必要な最大RAMは、各モデルカードの表で確認できます。

    画像

    3. ビルドツールの準備

    「Llama.cpp」は、インストール時に環境にあわせてソースからビルドして利用するため、ビルドツールが必要です。

    3-1. macOS

    (1) 「Xcode」がインストールされていることを確認。

    $ xcode-select -p
    /Applications/Xcode-beta.app/Contents/Developer

    (2) Xcodeが見つからない場合はインストール。

    $ xcode-select --install

    3-2. Windows

    (1) 「w64devkit」(w64devkit-1.19.0.zip)をダウンロードして解凍。
    Windows 用のポータブル C / C++ 開発キットになります。
    (2) 「w64devkit」直下の「bin」のパスをWindowsの環境変数のPATHに追加。

    4. Llama.cppの実行

    「Llama.cpp」の実行手順は、次のとおりです。

    (1) リポジトリのクローン。

    $ git clone https://github.com/ggerganov/llama.cpp
    $ cd llama.cpp

    (2) ビルド。

    $ make

    (3) ダウンロードしたモデルを「llama.cpp/models」に配置。

    (4) 推論の実行。

    $ ./llama-cli -m ./models/llama-2-7b-chat.ggmlv3.q4_K_M.bin --temp 0.1 -p "### Instruction: What is the height of Mount Fuji?
    ### Response:"
    ### Instruction: What is the height of Mount Fuji?
    ### Response: The height of Mount Fuji is 3,776 meters (12,421 feet) above sea level.
    
     [end of text]
    
    llama_print_timings:        load time =   556.13 ms
    llama_print_timings:      sample time =    95.63 ms /    30 runs   (    3.19 ms per token,   313.70 tokens per second)
    llama_print_timings: prompt eval time =   291.74 ms /    19 tokens (   15.35 ms per token,    65.13 tokens per second)
    llama_print_timings:        eval time =  2158.23 ms /    29 runs   (   74.42 ms per token,    13.44 tokens per second)
    llama_print_timings:       total time =  2573.64 ms
    ggml_metal_free: deallocating
    Log end

    【翻訳】
    ### Instruction:
    富士山の高さはどれくらいですか?
    ### Response: 富士山の高さは海抜 3,776 メートル (12,424 フィート) です。

    [end of text]

    時間の説明は次のとおりです。

    ・load time : モデルのロード時間
    ・sample time : プロンプトのトークン化 (サンプリング) 時間
    ・prompt eval time : トークン化されたプロンプトの処理時間
    ・eval time : 応答トークンの生成時間 (トークン出力を開始してからの時間のみを測定)
    ・total time : 合計時間

    5. llama-cpp-pythonの実行

    「llama-cpp-python」は、「Llama.cpp」のPythonバインディングです。特徴は、次のとおりです。

    ・C API への低レベルのアクセス。
    ・テキスト補完用の高レベルPython API
    ・OpenAI準拠のAPIの提供
    ・LangChainとの互換性


    「llama-cpp-python」の実行手順は、次のとおりです。

    (1) Pythonの仮想環境の準備。

    (2) パッケージのインストール。

    $ pip install llama-cpp-python

    再インストールする時は、以下のリビルドオプションが必要になります。

    $ pip install --upgrade --force-reinstall llama-cpp-python --no-cache-dir

    (3) コードの作成。

    ・hello_ggml.py

    from llama_cpp import Llama
    
    # LLMの準備
    llm = Llama(model_path="./llama-2-7b-chat.ggmlv3.q4_K_M.bin")
    
    # プロンプトの準備
    prompt = """### Instruction: What is the height of Mount Fuji?
    ### Response:"""
    
    # 推論の実行
    output = llm(
        prompt,
        temperature=0.1,
        stop=["Instruction:", "Input:", "Response:", "\n"],
        echo=True,
    )
    print(output["choices"][0]["text"])

    (4) コードの実行。

    $ python hello_ggml.py
    ### Instruction: What is the height of Mount Fuji?
    ### Response: The height of Mount Fuji is 3,776 meters (12,424 feet) above sea level.

    【翻訳】
    ### Instruction:
    富士山の高さはどれくらいですか?
    ### Response: 富士山の高さは海抜 3,776 メートル (12,424 フィート) です。

    【おまけ】 Llama.cpp のパラメータ

    -h, --help : ヘルプ
    -i, --interactive : interactiveモードで実行
    --interactive-first : interactiveモードで実行し、入力待ち
    -ins, --instruct : interactiveモードで実行 (Alpacaモデルを使用)
    --multiline-input : 各行を「\」で終わらせず、複数行を書いたり貼り付けたりできる
    -r PROMPT, --reverse-prompt PROMPT : PROMPTで生成を停止 (複数プロンプトに複数回指定可能)
    --color : 色でプロンプトとユーザー入力を識別
    -s SEED, --seed SEED : シード (default: -1, ランダム < 0)
    -t N, --threads N : スレッド数 (default: 8)
    -p PROMPT, --prompt PROMPT : プロンプト (default: empty)
    -e : プロンプトのエスケープシーケンスを処理 (\n, \r, \t, \', \", \\)
    --prompt-cache FNAME : ファイルでプロンプト状態をキャッシュし、起動を高速化 (default: none)
    --prompt-cache-all : ユーザー入力と生成テキストをキャッシュに保存。interactiveモードなどの対話型オプションでは未サポート
    --prompt-cache-ro : プロンプトのキャッシュを使用。更新はしない
    --random-prompt : ランダムなプロンプトで開始
    --in-prefix STRING : プレフィックス (default: empty)
    --in-suffix STRING : サフィックス (default: empty)
    -f FNAME, --file FNAME : プロンプトファイル
    -n N, --n-predict N : 予測するトークン数 (default: -1, -1 = infinity)
    -c N, --ctx-size N : プロンプトコンテキストのサイズ (default: 512)
    -b N, --batch-size N : 高速処理のためのバッチサイズ (default: 512)
    -gqa N, --gqa N : グループ化クエリーアテンションファクター (LLaMAv2 70Bでは8) (default: 1)
    --top-k N : top-k サンプリング (default: 40, 0 = disabled)
    --top-p N : top-p サンプリング (default: 0.9, 1.0 = disabled)
    --tfs N : tail free サンプリングのパラメータ z (default: 1.0, 1.0 = disabled)
    --typical N : locally typical サンプリングのパラメータ p (default: 1.0, 1.0 = disabled)
    --repeat-last-n N : ペナルティを考慮する最後のn個のトークン (default: 64, 0 = disabled, -1 = ctx_size)
    --repeat-penalty N : repeatペナルティ (default: 1.1, 1.0 = disabled)
    --presence-penalty N : presenceペナルティ (default: 0.0, 0.0 = disabled)
    --frequency-penalty N : frequencyペナルティ (default: 0.0, 0.0 = disabled)
    --mirostat N : Mirostatサンプリング。Top K、Nucleus、Tail Free、Locally Typicalサンプラーを使用しても無視される(default: 0, 0 = disabled, 1 = Mirostat, 2 = Mirostat 2.0)
    --mirostat-lr N : Mirostat学習率のパラメータ eta (default: 0.1)
    --mirostat-ent N : Mirostatターゲットエントロピーのパラメータ tau (default: 5.0)
    -l TOKEN_ID(+/-)BIAS, --logit-bias TOKEN_ID(+/-)BIAS : トークンがコンプリーションに登場する可能性の変更
    i.e. `--logit-bias 15043+1` to increase likelihood of token ' Hello',
    or `--logit-bias 15043-1` to decrease likelihood of token ' Hello'
    --grammar GRAMMAR : テキスト生成を成約する BNF-like grammar (grammars/ dir のサンプルを参照)
    --grammar-file FNAME : ファイルから grammar を読み込む
    --cfg-negative-prompt PROMPT : ネガティブプロンプトをガイダンスに使用 (default: empty)
    --cfg-scale N : ガイダンスの強さ (default: 1.000000, 1.0 = disable)
    --rope-freq-base N : RoPEの基本周波数 (default: 10000.0)
    --rope-freq-scale N : RoPE周波数スケーリング係数 (default: 1)
    --ignore-eos : EOSを無視して生成を続行 (implies --logit-bias 2-inf)
    --no-penalize-nl : 改行トークンにペナルティを与えない
    --memory-f32 : メモリのキーと値には f16 の代わりに f32 を使用 (非推奨) (default: disabled)
    --temp N : 温度。生成テキストのランダムさ (default: 0.8)
    --perplexity : プロンプトの各ctx windowに対するperplexityの計算
    --perplexity-lines : プロンプトの各行に対するperplexityの計算
    --keep : 最初のプロンプトから保持するトークン数 (default: 0, -1 = all)
    --chunks N : 処理するチャンクの最大数 (default: -1, -1 = all)
    --mlock : スワップや圧縮せずにRAMでモデルを保持
    --no-mmap : メモリマップモデルを使用しない(ロードが遅くなるが、mlockを使用しない場合はページアウトが減る可能性がある)
    --numa : 一部のNUMAシステムで役立つ最適化を試みる。
    --mtest : 最大メモリ使用量の計算
    --export : computation graph を'llama.ggml'にエクスポート
    --verbose-prompt : 生成前のプリントプロンプト
    --lora FNAME : LoRAアダプターの適用 (implies --no-mmap)
    --lora-base FNAME : LoRAアダプタが変更するレイヤのベースとして使用するオプションモデル
    -m FNAME, --model FNAME : モデルパス (default: models/7B/ggml-model.bin)

    【おまけ】 llama-cpp-pythonの主なAPI

    ・__init__()

    __init__(
        model_path, # モデルパス
        n_ctx=512, # 最大コンテキストサイズ
        n_parts=-1, # モデル分割数(-1:自動)
        n_gpu_layers=0, #
        seed=1337, # シード(-1:ランダム)
        f16_kv=True, # キー/値のキャッシュに半精度を使用
        logits_all=False, # 最後のトークンだけでなく、全トークンのログ返す
        vocab_only=False, # 語彙のみをロード (重みなし)
        use_mmap=True, # 可能であれば、mmapを使用
        use_mlock=False, # モデルのRAM保存を強制
       embedding=False, # 埋め込みモードのみ
        n_threads=None, # スレッド数(なし:自動)
        n_batch=512, # llama_eval呼び出し時のバッチ数
        last_n_tokens_size=64, # last_n_tokens dequeに保持するトークン最大数
        lora_base=None, # ベースモデルのパス
        lora_path=None, # LoRAファイルへのパス
        low_vram=False, #
        tensor_split=None, # モデルを複数のGPUに分割
        rope_freq_base=10000.0, # ロープサンプリングの基本周波数
        rope_freq_scale=1.0, # ロープサンプリングのスケールファクター
        verbose=True # 詳細出力
    )
    説明: コンストラクタ

    ・__call__()

    __call__(
        prompt, # プロンプト
        suffix=None, # 生成テキストに追加するサフィックス 
        max_tokens=128, # 生成テキストの最大トークン数 (0:無制限)
        temperature=0.8, # サンプリングの温度
        top_p=0.95, # サンプリングのtop-p
        logprobs=None, # 返すログプロブ数
        echo=False, # プロンプトをエコーするか
        stop=[], # 停止文字列リスト
        frequency_penalty=0.0, # frequencyペナルティ
        presence_penalty=0.0, # presenceペナルティ
        repeat_penalty=1.1, # リピートペナルティ
        top_k=40, # サンプリングのtop-k
        stream=False, # ストリーミング
        tfs_z=1.0, #
        mirostat_mode=0, #
        mirostat_tau=5.0, #
        mirostat_eta=0.1, #
        model=None, #
        stopping_criteria=None, #
        logits_processor=None #
    )
    説明: プロンプトからテキストを生成
    戻り値: CompletionまたはCompletionのストリーム
        (Union[Completion, Iterator[CompletionChunk]])

    ・create_completion()

    create_completion(
        prompt, # プロンプト
        suffix=None, # 生成テキストに追加するサフィックス
        max_tokens=128, # 生成テキストの最大トークン数 (0:無制限)
        temperature=0.8, # サンプリングの温度
        top_p=0.95, # サンプリングのtop-p
        logprobs=None, # 返すログプロブ数
        echo=False, # プロンプトをエコーするか
        stop=[], # 停止文字列リスト
        frequency_penalty=0.0, # frequencyペナルティ
        presence_penalty=0.0, # presenceペナルティ
        repeat_penalty=1.1, # リピートペナルティ
        top_k=40, # サンプリングのtop-k
        stream=False, # ストリーミング
        tfs_z=1.0, #
        mirostat_mode=0, #
        mirostat_tau=5.0, #
        mirostat_eta=0.1, #
        model=None, #
        stopping_criteria=None, #
        logits_processor=None #
    )
    説明
    : プロンプトからテキストを生成
    戻り値: CompletionまたはCompletionのストリーム
        (Union[Completion, Iterator[CompletionChunk]])

    ・create_chat_completion()

    create_chat_completion(
        messages, # メッセージリスト
        temperature=0.2, # サンプリングの温度
        top_p=0.95, # サンプリングのtop-p
        top_k=40, # サンプリングのtop-k
        stream=False, # ストリーミング
        stop=[], # 停止文字列リスト
        max_tokens=256, # 生成テキストの最大トークン数 (0:無制限)
        presence_penalty=0.0, # presenceペナルティ
        frequency_penalty=0.0, # frequencyペナルティ
        repeat_penalty=1.1, # リピートペナルティ
        tfs_z=1.0, #
        mirostat_mode=0, #
        mirostat_tau=5.0, #
        mirostat_eta=0.1, #
        model=None, #
        logits_processor=None #
    )
    説明
    : メッセージリストからチャット応答を生成
    戻り値: ChatCompletionまたはChatCompletionのストリーム
        (Union[ChatCompletion, Iterator[ChatCompletionChunk]])

    関連

    次回



     
     

    npaka

     
     
    プログラマー。iPhone / Android / Unity / ROS / AI / AR / VR / RasPi / ロボット / ガジェット。年2冊ペースで技術書を執筆。アニソン / カラオケ / ギター / 猫 twitter : @npaka123

    あなたへのおすすめ