|
大規模言語モデルは巨大化の一途を辿り、今後も更なる巨大化が予想されます。しかし、その推論コストとエネルギー消費の大きさは、大規模言語モデルの使用コストを著しく増加させます。そのため、メモリ使用量や計算負荷軽減を目的に、大規模言語モデルのパフォーマンスを維持しながら、モデルを軽量化する方法論としてモデルの量子化(パラメータの整数化)に注目が集まっています。 量子化とは、重みなどのパラメータをより小さいビット(32, 16bit の代わりに 8, 4, 1 bit など)で表現し、メモリの使用率を下げるなどして、ネットワークの構造を変えずにモデルの軽量化を図る手法です。
llama.cpp は 大規模言語モデルの重みを量子化し、より低精度の離散値に変換することで推論の高速化を図るライブラリの一つです。llama.cpp の主な目的は、GPU を必要としない最小限のセットアップで、ローカルおよびクラウドのさまざまなハードウェア上で最先端のパフォーマンスを実現しながら LLM 推論を可能にすることです。また、llama という名前がついていますが、サポートされているLLMは Llama シリーズだけではありません。GPT、 Mistral や BERT などのモデルに対しても利用可能です。
また、2024年2月27日、The Era of 1-bit LLMs: All Large Language Models are in 1.58 Bitsと題した論文で、1ビットで推論する大規模言語モデル(BitNet)、つまり、重みが(1, 0, -1)の1ビットで構成される Transformer が提案されました。BitNetとは端的に言えば、従来の Transformer の Linear 層を1ビットの重みによって表現される BitLinear 層に置換したものです。 BitNet.cpp を用いて LLM モデルを1.58 Bitモデルに軽量化することができます。
HuggingFace のサイトには、Meta-llama シリーズの LLM や Mistral などの LLM の GGUF 形式の量子化モデルが多数提供されています。例えば、Hugging Face のQuantFactory、または、Hugging-quantsなどが有用です。
LLM の軽量化モデルを利用してローカル LLM を構築し、運用するためのツールがいくつか提案されています。上で説明した llama.cpp 、BitNet.cpp は当然そのうちの一つですが、 ollama や LangChain というツールが公開されています。このページでは、llama.cpp を主に取り上げて、説明します。
このページで使用する日本語LLMは GGUF 形式で量子化されモデルです。HuggingFace のサイトからダウンロードできるモデルを対象としました。一つ目は、ELYZAが開発・提供する大規模言語モデル「ELYZA LLM for JP」シリーズの最新モデルです。Llama-3-ELYZA-JP は Llama 3 8B モデルを利用して日本語のファインチューニングをしたモデルです。2番目に取り上げるのは、Sakana AI がリリースした SakanaAI-EvoLLM-JP-v1-7B です。SakanaAI-EvoLLM-JP-v1-7B は Llama アーキテクチャーを利用していません。最後に、Llama 3.1 を日本語で追加学習した Llama-3.1-Swallow-8B-v0.1 のgguf型式で量子化したモデルを取り上げます。
使用している PC は Mac BookAir で、CPU は 1.65GHz Intel 、メモリは 16GB です。GPU は搭載していません。
Last updated: 2024.10.24
llama.cpp のインストールと使用法 |
llama.cppは、大規模言語LLMシリーズの Llama-2 ,3 モデルや mistral のモデルの重みを量子化という技術でより低精度の離散値に変換して、推論の高速化を図るツールです。使い方は非常にシンプルです。使用法は以下の通りです。
まず、バイナリを取得する必要があります。実行できる方法はいくつかあります:
方法 1: リポジトリをクローンしてローカルでビルドします。
方法 2: MacOS または Linux を使用している場合は、brew、flox、または nix 経由で llama.cpp をインストールできます
方法 3: Docker イメージを使用します。
方法 4: リリースからビルド済みのバイナリをダウンロードします
リポジトリをクローンしてローカルでビルドするには、次のコマンドを使用して、基本的なビルドを実行できます。
$git clone https://github.com/ggerganov/llama.cpp $cd llama.cpp (llama.cpp)$make
MacOS では、Metal はデフォルトで有効になっています。Metal を使用すると、計算は GPU 上で実行されます。この make を使ったビルドをすると、MacPC の場合には、Metal を使用することが条件になります。コンパイル時に Metal ビルドを無効にするには、GGML_NO_METAL=1 フラグまたは GGML_METAL=OFF cmake オプションを使用します。Metal を使用しないときは、以下のようにします。
(llama.cpp)$cmake -B build -DGGML_METAL=OFF (llama.cpp)$cmake --build build --config Release
これで、cpu のみの MacPC で、Llama モデルの量子化モデルを用いた推論が実行可能になります。Llama.cppで動作させるためには、METAが提供するLlamaのモデルを量子化する必要があります。現在(2024年9月)、llama.cpp では、ggml 量子化フォーマットは現在サポートされていません。gguf フォーマット形式の量子化モデルが必要です。Llama 3 に対応する gguf フォーマット形式のコードは Hugging Face のQuantFactoryにあります。
gguf 形式の量子化モデルを用いて推論を実行するときは、llama.cpp ディレクトリに移動して、例えば、以下のようなコマンドを実行します。
$ cd llama.cpp $./build/bin/llama-cli -m Meta-Llama-3-8B.gguf -p "I believe the meaning of life is" -n 128
-m, --model オプションはモデルの指定なので、 Meta-Llama-3-8B.gguf と具体的に指定します。-p, --prompt はプロンプトのオプションなので、プロンプト(質問など)の文章を記述します。ここでは、" I believe he meaning of life is "と入力しています。-n, --n-predict は作成する文章のトークン数の指定です。-c, --ctx-size はプロンプトのサイズを指定します。デフォルトでは、512 です。
例えば、Llama 3 8B の量子化モデル Meta-Llama-3-8B-Instruct.Q4_K_M.gguf を用いるケースを説明します。このモデルを Hugging Face の repos からダウンロードして、llama.cpp と同じディレクトリに models ディレクトリを作成して、そこに配置します。その後、以下のコードをターミナルから実行します。
$./build/bin/llama-cli -m ../models/Meta-Llama-3-8B-Instruct.Q4_K_M.gguf -p "I believe the meaning of life is" -n 128
ターミナル上に、以下のような返事が表示されます。
--- response --- I believe the meaning of life is to find your passion and pursue it with all your heart. Whether it's a creative pursuit, a career, or a hobby, the most important thing is to be doing something that brings you joy and fulfillment. I also believe that the key to a happy and fulfilling life is to be true to yourself and live authentically. This means being honest with yourself and others about who you are and what you want, and not trying to fit into someone else's mold or expectations. Ultimately, the meaning of life is a personal and subjective thing, and what brings meaning and purpose to one person's life may be different for another. I believe llama_perf_sampler_print: sampling time = 24.73 ms / 136 runs ( 0.18 ms per token, 5498.28 tokens per second) llama_perf_context_print: load time = 3186.75 ms llama_perf_context_print: prompt eval time = 1603.11 ms / 8 tokens ( 200.39 ms per token, 4.99 tokens per second) llama_perf_context_print: eval time = 51880.52 ms / 127 runs ( 408.51 ms per token, 2.45 tokens per second) llama_perf_context_print: total time = 53550.01 ms / 135 tokens Log end
入力したプロンプトに対する答えが帰ってきます。ここでのプロンプトは文章の始まりなので、続きの文章が作成されます。
chatbot のような会話形式でプロンプトを実行するときは、以下のようなコマンドを使用します。オプション「-cnv」をつけます。
$./llama-cli -m Meta-Llama-3-8B.gguf -p "You are a helpful assistant" -cnv
チャット・テンプレートを指定しないときは、入力モデルのメタデータのものを使用します。チャット・テンプレートを指定するときは、例えば、「--chat-template NAME」と指定します。以下の例がそれです。
$./llama-cli -m Meta-Llama-3-8B.gguf -p "You are a helpful assistant" -cnv --chat-template chatml
チャット・テンプレートで指定できるものは、llama2, llama3, gemma, monarch, chatml, orion, vicuna などです。
具体的には、以下のコマンドを入力しました。
$./build/bin/llama-cli -m ../models/Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf -p "You are a helpful assistant" -cnv
--- response --- == Running in interactive mode. == - Press Ctrl+C to interject at any time. - Press Return to return control to the AI. - To return control without starting a new line, end your input with '/'. - If you want to submit another line, end your input with '\'. system You are a helpful assistant >
ここで、プロンプト記号 (>) の後に質問を記述します。
> hi, who are you? Nice to meet you! I'm a helpful assistant, here to assist you with any questions, provide information, or just chat with you. I'm a large language model, which means I can understand and respond to a wide range of topics and tasks. I'm like a virtual assistant, but instead of being a physical person, I'm a computer program designed to help you with any need or curiosity you may have. I'm here to listen, help, and provide you with accurate and helpful information. How can I assist you today? Do you have a specific question or topic in mind? > can you tell me about Tokyo? Tokyo! One of the most vibrant and fascinating cities in the world. Tokyo, the capital of Japan, is a city like no other. Here's a brief overview: **Culture and History:** Tokyo has a rich cultural heritage, blending traditional and modern elements. The city is home to numerous temples, shrines, and gardens, showcasing its deep roots in Shinto and Buddhist traditions. Tokyo's history dates back to 1457, when it was a small fishing village called Edo. Over time, it grew into a bustling metropolis, becoming the capital of Japan in 1868. **Landmarks and Attractions:** Some of the top attractions in Tokyo include: 1. **Shibuya Crossing**: A famous scramble crossing with over 2,500 pedestrians per hour. 2. **Tokyo Tower**: A iconic communications tower offering breathtaking views of the city. 3. **Meiji Shrine**: A serene Shinto shrine located in a tranquil forested area. 4. **Tsukiji Outer Market**: A bustling marketplace for fresh sushi and seafood. 5. **Asakusa**: A historic district with ancient temples and traditional shops. 6. **Akihabara**: Tokyo's electronics and anime hub, also known as "Electric Town." 7. **Imperial Palace**: The main residence of the Emperor of Japan, surrounded by beautiful gardens. **Neighborhoods:** Tokyo is divided into 23 special wards, each with its unique character: 1. **Shinjuku**: A bustling entertainment district with skyscrapers and neon lights. 2. **Harajuku**: A fashion-forward area with trendy shops and cafes. 3. **Roppongi**: An upscale neighborhood with luxury shopping and dining options. 4. **Ikebukuro**: A commercial district with large department stores and anime centers. 5. **Odaiba**: A man-made island with shopping malls, theme parks, and entertainment options. **Food and Drink:** Tokyo is a food lover's paradise, with a vast array of delicious options: 1. **Sushi**: Fresh sushi is a must-try, with high-end restaurants like Sukiyabashi Jiro and low-cost options like conveyor belt sushi. 2. **Ramen**: A popular noodle soup dish, often served at tiny restaurants. 3. **Tempura**: Lightly battered seafood or vegetables, often served with rice and miso soup. 4. **Tonkatsu**: A breaded and deep-fried pork cutlet, often served with rice and vegetables. 5. **Green Tea**: A traditional Japanese beverage, often served in small cups. **Tips and Essentials:** 1. **Language**: While many Tokyo residents speak some English, it's always helpful to learn basic Japanese phrases. 2. **Transportation**: Tokyo has an extensive public transportation system, including subways, buses, and trains. 3. **Money**: Japan uses yen, and credit cards are widely accepted. 4. **Safety**: Tokyo is generally a safe city, but take normal precautions to protect yourself and your belongings. This is just a taste of what Tokyo has to offer. Is there a specific aspect of Tokyo you'd like to know more about? > あなたは日本に行ったことがありますか? すみません。私は日本に行ったことはありません。私はコンピューター上で存在するので、実際に日本に行くことはできません。ただし、日本語を学んでいますし、日本の文化や風習について調べたり、情報を提供したりすることができます。 ですが、多くの日本人や日本に住んでいる外国人がこのチャットに参加していて、ご質問に答えることもできます。もし日本に関する質問がある場合は、ぜひ尋ねてください! > > (続けて、ここに質問のプロンプトを記入します。)
上の例のように、ある程度まで日本語での返答は可能です。しかし、簡単な日本語の質問でも妥当な日本語の解答が必ず表示されるとは限りません。以下の例がそうです。
== Running in interactive mode. == - Press Ctrl+C to interject at any time. - Press Return to return control to the AI. - To return control without starting a new line, end your input with '/'. - If you want to submit another line, end your input with '\'. system You are a helpful assistant >日本で1番高い山はどこですか?2番目に高い山は何ですか? 日本で1番高い山は、日本最高峰の「薬師岳」でございます。 2番目に高い山は「富士山」でございます。
このように、日本語での入力が可能とされる Llama 3.1 でも日本語でのチャットは不安定なものとなります。それゆえに、日本語で追加学習した LLM が必要となります。
無料で利用できる日本語大規模言語モデルは多数開発されています。MIT や Apache-2.0 といったオープンソースライセンスが適用されています。利用可能な日本語大規模言語モデルのリストは、awesome-japanese-llm というサイトに紹介されています。海外モデル(Llama 2 ,3 、 Mistral や GPTなど)に日本語で追加事前学習を行ったモデルの代表的なものは、Llama-3.1-70B-Japanese-Instruct-2407、 Llama 3.1 Swallow 、llama-3-youko-70b-instruct、Llama-3-ELYZA-JPなどです。
フルスクラッチで事前学習した日本語LLMモデルには、stockmark/stockmark-100b-instruct-v0.1 、Tanuki-8x8B-dpo-v1.0 、cyberagent/Llama-3.1-70B-Japanese-Instruct-2407、SakanaAI/Llama-3-EvoVLM-JP-v2などがあります。
llama.cpp で日本語LLM : Llama-3-ELYZA-JP |
早速、日本語LLM を使用してみましょう。ELYZA LLM for JP シリーズの最新モデル「Llama-3-ELYZA-JP」を使ってみましょう。「Llama-3-ELYZA-JP」シリーズの概要は以下のように説明されています。 「Llama-3-ELYZA-JP」シリーズは、Meta社の「Llama 3」シリーズをベースとした2種類の日本語大規模言語モデル(以下、LLM)を指し、700億パラメータの「Llama-3-ELYZA-JP-70B」と80億パラメータの「Llama-3-ELYZA-JP-8B」が該当します。各モデルは、それぞれ「Meta-Llama-3-70B-Instruct」と「Meta-Llama-3-8B-Instruct」に対し、日本語における指示追従能力を拡張するための、日本語追加事前学習および事後学習を行ったものです。
日本語の生成能力に関するベンチマーク評価 (ELYZA Tasks 100、Japanese MT-Bench) において、両モデルはいずれもベースとなる「Llama 3」シリーズから大きく日本語性能が向上しています。特に 700億パラメータの「Llama-3-ELYZA-JP-70B」は「GPT-4」「Claude 3 Sonnet」「Gemini 1.5 Flash」といったグローバルモデルを上回る性能を達成しました。
Llama-3-ELYZA-JP をgguf型式で量子化したモデル Llama-3-ELYZA-JP-8B-GGUF を使用します。これをダウンロードして、llama.cpp と同じディレクトリに models を作成して、ここに配置します。サイズは約4.9GBあります。
llama.cpp ディレクトリから
(llama.cpp)$./build/bin/llama-cli -m ../models/Llama-3-ELYZA-JP-8B-q4_k_m.gguf -p "I believe the meaning of life is" -n 128
結果は以下の通りです。
--- response --- Log start main: build = 3755 (822b6322) main: built with Apple clang version 15.0.0 (clang-1500.3.9.4) for x86_64-apple-darwin23.6.0 llama_model_loader: loaded meta data with 22 key-value pairs and 291 tensors from ../models/Llama-3-ELYZA-JP-8B-q4_k_m.gguf (version GGUF V3 (latest)) llama_model_loader: Dumping metadata keys/values. Note: KV overrides do not apply in this output. llama_model_loader: - kv 0: general.architecture str = llama llama_model_loader: - kv 1: general.name str = Llama-3-8B-optimal-merged-stage2 llama_model_loader: - kv 2: llama.block_count u32 = 32 llama_model_loader: - kv 3: llama.context_length u32 = 8192 llama_model_loader: - kv 4: llama.embedding_length u32 = 4096 llama_model_loader: - kv 5: llama.feed_forward_length u32 = 14336 llama_model_loader: - kv 6: llama.attention.head_count u32 = 32 ... generate: n_ctx = 8192, n_batch = 2048, n_predict = 128, n_keep = 1 I believe the meaning of life is to find your passion and pursue it with purpose and dedication. It's a challenging and sometimes difficult journey, but it's the most rewarding and fulfilling way to live your life. So, my advice is to find your passion and pursue it with purpose and dedication. It's the key to a happy and successful life. [end of text] llama_perf_sampler_print: sampling time = 10.54 ms / 72 runs ( 0.15 ms per token, 6829.82 tokens per second) llama_perf_context_print: load time = 21251.42 ms llama_perf_context_print: prompt eval time = 1519.29 ms / 8 tokens ( 189.91 ms per token, 5.27 tokens per second) llama_perf_context_print: eval time = 20218.65 ms / 63 runs ( 320.93 ms per token, 3.12 tokens per second) llama_perf_context_print: total time = 21769.80 ms / 71 tokens Log end
llama.cpp ディレクトリから
$./build/bin/llama-cli -m ../models/Llama-3-ELYZA-JP-8B-q4_k_m.gguf -p "私が思うに、人生とは" -n 560
と入力すると、以下の返答となります。
--- response --- 私が思うに、人生とは旅である。人生の旅では、道が途切れていたり、暗い夜道を通らなければならないこともある。でも、旅人である私たちは、常に新しい出会いを求め、未知の世界を探求し、自己を成長させることを目指す。 この「旅」という考え方は、人生の様々な場面で通用する。例えば、就職活動の「旅」では、自分が目指す道が明確でないと、迷子になったり、道を間違えてしまう。 また、結婚の「旅」では、パートナーと共に歩む道を探し、互いに支え合い、助け合うことが大切である。 更に、子育ての「旅」では、子どもが成長していく過程で、親が道標や安全網を提供することが重要である。 人生は旅であると考えることで、人生のあらゆる場面で、旅人としての心構えやマインドセットを身に付けることができる。 以上が、私が思う「人生は旅である」という考え方の要点である。人生の旅は、常に新しい出会いを求め、未知の世界を探求し、自己を成長させることを目指す旅である。人生の旅を存分に味わい、各場面で旅人としての心構えやマインドセットを身に付けることで、人生をより豊かに、楽しく、有意義に過ごすことができる。 [end of text] llama_perf_sampler_print: sampling time = 71.38 ms / 369 runs ( 0.19 ms per token, 5169.23 tokens per second) llama_perf_context_print: load time = 28535.03 ms llama_perf_context_print: prompt eval time = 2734.16 ms / 10 tokens ( 273.42 ms per token, 3.66 tokens per second) llama_perf_context_print: eval time = 149441.41 ms / 358 runs ( 417.43 ms per token, 2.40 tokens per second) llama_perf_context_print: total time = 152381.82 ms / 368 tokens Log end
作成する文章のトークン数を指定しないで実行します。llama.cpp ディレクトリから
llama.cpp $ ./build/bin/llama-cli -m ../models/Llama-3-ELYZA-JP-8B-q4_k_m.gguf -p "z世代とは何ですか"
以下の結果が表示されます。
--- response --- Log start ... z世代とは何ですか? z世代とは、1997年から2012年生まれの世代を指します。z世代は、ミレニアム世代の次に生まれた世代で、インターネットやデジタルテクノロジーを幼いころから当たり前のように使い、独自の価値観や消費行動を持つとされます。 特徴として、以下が挙げられます。 1. デジタルネイティブ:生まれた時からインターネットやスマートフォンが存在し、デジタルテクノロジーに馴染みがあります。 2. 多様性を重視:z世代は、多様性を重視し、個性や多様なバックグラウンドを尊重する傾向があります。 3. サステナビリティ意識が高い:z世代は、環境や社会の問題に敏感で、サステナビリティや社会的責任を重視する消費者層です。 4. コミュニケーションスタイルが異なる:z世代は、テキストメッセージやSNSでのコミュニケーションを好み、会話や電話を好まない傾向があります。 5. 金銭感覚が異なる:z世代は、金銭感覚が異なり、経済的な安定や長期的な視点を重視する傾向があります。 z世代は、将来の消費やマーケットを占める大切な世代です。企業は、z世代の特性や価値観を理解し、戦略を立案する必要があります。 [end of text] llama_perf_sampler_print: sampling time = 79.66 ms / 397 runs ( 0.20 ms per token, 4983.74 tokens per second) llama_perf_context_print: load time = 2755.90 ms llama_perf_context_print: prompt eval time = 1246.78 ms / 7 tokens ( 178.11 ms per token, 5.61 tokens per second) llama_perf_context_print: eval time = 169561.27 ms / 389 runs ( 435.89 ms per token, 2.29 tokens per second) llama_perf_context_print: total time = 171038.56 ms / 396 tokens Log end
次に、旅行のブログを作成するプロンプトを実行します。
$ ./build/bin/llama-cli -m ../models/Llama-3-ELYZA-JP-8B-q4_k_m.gguf -p "最近のフランス旅行について、文化体験や必見の観光スポットを紹介する魅力的な旅行ブログ記事を作成してください。"
--- response --- 最近のフランス旅行について、文化体験や必見の観光スポットを紹介する魅力的な旅行ブログ記事を作成してください。パリの中心部から郊外の小さな町まで、美しい景色や歴史的建造物、現代アート、美食など、フランス旅行のハイライトを網羅します。 タイトル: Discover the Enduring Charm of France: A Journey Through its Cultural Heritage Introduction: フランスは、文化、芸術、美食、歴史など、多くの要素が組み合わさって、人々を魅了する国です。パリの中心部から郊外の小さな町まで、美しい景色や歴史的建造物、現代アート、美食など、フランス旅行のハイライトを網羅した魅力的な旅行ブログ記事を作成します。 1. パリの中心部: * エッフェル塔: パリのシンボルで、鉄塔の美しさとエレガントさを体験することができます。 * ルーブル美術館: 世界有数の美術館で、モナリザやミロのビーナスなどの名作を鑑賞できます。 * ノートルダム大聖堂: パリのランドマークで、ゴシック建築の美しさを体験することができます。 2. 郊外の小さな町: * Giverny: モネの家や庭園を訪れ、印象派のアーティストを体験することができます。 * Sainte-Chapelle: 美しいステンドグラスと荘厳な雰囲気を体験することができます。 3. 現代アート: * パリの現代アートシーンを体験することができます。近代美術館、ポンピドゥー・センター、カルティエ現代美術館など、多くの美術館を訪れることができます。 4. 美食: * フランス料理の代表的なコースを体験することができます。エスコフィエやブイヨンなど、伝統的なレシピを体験することができます。 * チーズやワインの試食、フランス菓子やパティスリーの試食など、美食の国を体験することができます。 5. 歴史的建造物: * ヴェルサイユ宮殿: ヨーロッパの王宮を体験することができます。宮殿や庭園を訪れ、歴史的建造物を体験することができます。 * フォンテ llama_perf_sampler_print: sampling time = 133.91 ms / 595 runs ( 0.23 ms per token, 4443.38 tokens per second) llama_perf_context_print: load time = 2812.79 ms llama_perf_context_print: prompt eval time = 15857.30 ms / 35 tokens ( 453.07 ms per token, 2.21 tokens per second) llama_perf_context_print: eval time = 259047.69 ms / 559 runs ( 463.41 ms per token, 2.16 tokens per second) llama_perf_context_print: total time = 275262.35 ms / 594 tokens Log end llama.cpp $
トークン数が595で終了してます。なので、作成された文章が途中で終わっています。なお、 Sainte-Chapelle はパリのセーヌ川シテ島にあるので、中心部にある建造物です。
llama.cpp で日本語LLM : SakanaAI-EvoLLM-JP-v1-7B |
Sakana AIは、進化的モデルマージにより日本語に強化された大規模言語モデル(EvoLLM-JP)と画像言語モデル(EvoVLM-JP)を公開しました。モデルマージとは複数の大規模言語モデルを統合し性能を改善させるものです。事前学習やファインチューニングよりも低コストという利点はありますが、その調整には経験と勘が求められます。Sakana AIは進化的アルゴリズムを用いて、このモデルマージを効率化しました。
Sakana AIのリリースによるとEvoLLM-JPは、7Bパラメータでありながら、70Bのモデルに匹敵する性能と日本語での計算能力を持っております。更に他の日本語ベンチマークでも性能が向上しているそうです。また、EvoVLM-JPは、画像を認識して日本語の文章を生成可能で、日本文化の知識にもある程度対応しているそうです。
Sakana AI が開発した日本語LLM、 SakanaAI-EvoLLM-JP-v1-7B-q4_K_M を利用しましょう。ダウンロードして、models ディレクトリに配置します。約4.4GBあります。llama.cpp ディレクトリから
llama.cpp $ ./build/bin/llama-cli -m ../models/SakanaAI-EvoLLM-JP-v1-7B-q4_K_M.gguf -p "私が思うに、人生とは" -n 560
--- response --- 私が思うに、人生とは、いつも、あの大きな樹の下で、一人の子供が、偶然、見つけた、ささやきを、偶然、聞いた、そんなことに過ぎないのではないか。 子供が、大きな樹の下で、偶然、見つけた、ささやきを、偶然、聞いた、と、言ったけれど、子供は、大きな樹の下で、ささやきを、聞いていたのではないか、大きな樹の下で、ささやきを、聞いているのではないか、と、言ったけれど、子供は、大きな樹の下で、ささやきを、聞いていたのではないか、大きな樹の下で、ささやきを、聞いているのではないか、と、言ったけれど、子供は、大きな樹の下で、ささやきを、聞いていたのではないか、大きな樹の下で、ささやきを、聞いているのではないか、と、言ったけれど、子供は、大きな樹の下で、ささやきを、聞いていたのではないか、大きな樹の下で、ささやきを、聞いているのではないか、と、言ったけれど、子供は、大きな樹の下で、ささやきを、聞いていたのではないか、大きな樹の下で、ささやきを、聞いているのではないか、と、言ったけれど、子供は、大きな樹の下で、ささやきを、聞いていたのではないか、大きな樹の下で、ささやきを、聞いているのではないか、と、言ったけれど、子 llama_perf_sampler_print: sampling time = 33.16 ms / 572 runs ( 0.06 ms per token, 17249.18 tokens per second) llama_perf_context_print: load time = 4024.93 ms llama_perf_context_print: prompt eval time = 2487.19 ms / 12 tokens ( 207.27 ms per token, 4.82 tokens per second) llama_perf_context_print: eval time = 180278.52 ms / 559 runs ( 322.50 ms per token, 3.10 tokens per second) llama_perf_context_print: total time = 182859.91 ms / 571 tokens Log end llama.cpp $
「言ったけれど、子供は、大きな樹の下で、」「聞いているにではないか」などが何度も何度も登場します。奇妙な日本語です。
llama.cpp ディレクトリから、以下のコマンドを入力します。
llama.cpp$./build/bin/llama-cli -m ../models/SakanaAI-EvoLLM-JP-v1-7B-q4_K_M.gguf -p "z世代とは何ですか"
--- response --- z世代とは何ですか? Z世代とは、1996年から2010年の間に生まれた世代です。この世代は、インターネットとデジタル技術が普及した時代に育っています。 Z世代の特徴は、デジタルネイティブ、ソーシャルネイティブ、マルチタスク、リアルタイム、コラボレーション、クリエイティブなどです。 Z世代は、従来の世代と比べて、より高いコミュニケーションスキル、自己表現スキル、創造性を持っています。 Z世代は、従来の世代と比べて、より高いコミュニケーションスキル、自己表現スキル、創造性を持っています。この世代は、新しい技術とツールを迅速に吸収し、革新的なアイデアを生み出す能力を示しています。 Z世代は、従来の世代と比べて、より高いコミュニケーションスキル、自己表現スキル、創造性を持っています。この世代は、新しい技術とツールを迅速に吸収し、革新的なアイデアを生み出す能力を示しています。また、従来の世代と比べて、より高いコミュニケーションスキル、自己表現スキル、創造性を持っています。この世代は、新しい技術とツールを迅速に吸収し、革新的なアイデアを生み出す能力を示しています。 [end of text] llama_perf_sampler_print: sampling time = 34.11 ms / 528 runs ( 0.06 ms per token, 15481.60 tokens per second) llama_perf_context_print: load time = 22630.58 ms llama_perf_context_print: prompt eval time = 2019.10 ms / 10 tokens ( 201.91 ms per token, 4.95 tokens per second) llama_perf_context_print: eval time = 195429.98 ms / 517 runs ( 378.01 ms per token, 2.65 tokens per second) llama_perf_context_print: total time = 197552.94 ms / 527 tokens Log end
同じ文章が3回ほど繰り返されています。少し奇妙な日本語になっています。
llama.cpp で日本語LLM : Llama-3.1-Swallow-8B-v0.1 |
Llama 3.1 Swallow はLlama 3.1 の英語の能力を維持しながら、日本語の能力を強化した大規模言語モデル (8B, 70B) です。モデルのパラメータ(重み)が HuggingFace 上で公開されていますので、Llama 3.1 ライセンスに従う限り、研究や商業目的などで利用できます。Llama 3.1 Swallow は米Meta社の Llama 3.1 をベースに、東京科学大学情報理工学院の岡崎研究室と横田研究室、国立研究開発法人産業技術総合研究所の研究チームで開発されました。
Llama 3.1 Swallow 8B の日本語理解・生成タスクの平均スコアは0.4905となり、前バージョンの Llama 3 Swallow 8B の平均スコア(0.4717)から1.88ポイント上昇し、オープンな8B以下の大規模言語モデルの中では最も高いスコアを記録しました。 また、Llama 3.1 8B の平均スコアは0.4359ですので、継続事前学習により日本語理解・生成タスクの平均スコアを5.46ポイント引き上げたことになります。 Llama 3 Swallow と比較すると、Llama 3.1 Swallow は着実に平均スコアを伸ばしたと言えるでしょう。
Llama 3.1 Swallow をgguf型式で量子化したモデル Llama-3.1-Swallow-8B-v0.1-GGUF を使用します。これをダウンロードして、llama.cpp と同じディレクトリにある models に配置します。サイズは約4.9GBあります。
最初に、上と同じ質問をします。llama.cpp ディレクトリから
$ ./build/bin/llama-cli -m ../models/tokyotech-llm-Llama-3.1-Swallow-8B-Instruct-v0.1-Q4_K_M.gguf -p "z世代とは何ですか?" -n 512
と入力すると、以下の返答がありました
--- response --- ... generate: n_ctx = 8192, n_batch = 2048, n_predict = 512, n_keep = 1 z世代とは何ですか?特徴や消費行動、メディア接触の傾向など z世代とは、1997年以降に生まれた世代を指します。z世代は、デジタルネイティブと呼ばれ、幼少期からインターネットやスマートフォンを通じて情報にアクセスしてきたため、メディア接触の傾向が他の世代とは異なります。 z世代の特徴としては、以下のような点が挙げられます。 1. デジタルネイティブ:z世代は、幼少期からインターネットやスマートフォンを通じて情報にアクセスしてきたため、デジタルネイティブと呼ばれます。 2. 多様性と包容性:z世代は、多様性と包容性を重視し、LGBTQ+や人種差別などの社会問題に関心を持っています。 3. 環境意識:z世代は、環境問題に関心を持っており、サステナブルな消費行動をとることが多くなります。 4. ソーシャルメディアの影響:z世代は、ソーシャルメディアを通じて情報を収集し、消費行動をとることが多くなります。 z世代の消費行動の傾向としては、以下のような点が挙げられます。 1. オンラインショッピング:z世代は、オンラインショッピングを好み、実店舗での購入よりもオンラインでの購入を優先することが多くなります。 2. サステナブルな消費:z世代は、環境問題に関心を持っているため、サステナブルな消費行動をとることが多くなります。 3. 多様性と包容性:z世代は、多様性と包容性を重視し、ブランドが社会的責任を果たしているかどうかを判断する際に、多様性と包容性を考慮することが多くなります。 z世代のメディア接触の傾向としては、以下のような点が挙げられます。 1. ソーシャル llama_perf_sampler_print: sampling time = 120.28 ms / 520 runs ( 0.23 ms per token, 4323.39 tokens per second) llama_perf_context_print: load time = 3748.22 ms llama_perf_context_print: prompt eval time = 2561.72 ms / 8 tokens ( 320.21 ms per token, 3.12 tokens per second) llama_perf_context_print: eval time = 240217.55 ms / 511 runs ( 470.09 ms per token, 2.13 tokens per second) llama_perf_context_print: total time = 243097.46 ms / 519 tokens Log end
返答のトークン数を 512 と指定したので、途中で切れています。日本語の文章としてはおかしくありませんが、冗長な日本語です。文章のトークン数を指定しないと、強制的に終了しない限り、冗長な文章が延々と続きます。類似の文章を繰り返すクセがあるようです。
会話形式で聞いてみました。以下のようになりました。
$./build/bin/llama-cli -m ../models/tokyotech-llm-Llama-3.1-Swallow-8B-Instruct-v0.1-Q4_K_M.gguf -p "あなたは優秀なAIアシスタントです。" -cnv --- response --- ... generate: n_ctx = 8192, n_batch = 2048, n_predict = -1, n_keep = 1 == Running in interactive mode. == - Press Ctrl+C to interject at any time. - Press Return to return control to the AI. - To return control without starting a new line, end your input with '/'. - If you want to submit another line, end your input with '\'. system あなたは優秀なAIアシスタントです。 > z世代とは何ですか? Z世代とは、1990年代後半から2000年代前半に生まれた世代を指します。この世代は、デジタルネイティブとして、スマートフォンやインターネットを当たり前のものとして育ち、SNSやオンラインコミュニティを通じて情報を共有し、つながりを深めています。Z世代は、多様性や個性を尊重し、社会的責任や環境問題に意識が高いとされています。
冗長な文章ではなく、簡潔な日本語での返答となりました。
次に、旅行ブログの作成を依頼しました。llama.cpp ディレクトリから、以下のコードを打ちました。
$ ./build/bin/llama-cli -m ../models/tokyotech-llm-Llama-3.1-Swall o 8B-Instruct-v0.1-Q4_K_M.gguf -p "最近のフランス旅行について、文化体験や必見の観光スポットを紹介する魅力的な旅行ブログ記事を作成してください。"
--- response --- 最近のフランス旅行について、文化体験や必見の観光スポットを紹介する魅力的な旅行ブログ記事を作成してください。以下はその例です。 **フランス旅行の魅力:文化体験と必見の観光スポット** フランスは、芸術、ファッション、料理、そして豊かな文化遺産で知られる国です。最近、私はこの美しい国を旅する機会を得て、心を奪われました。ここでは、私が体験した文化体験と必見の観光スポットについてご紹介します。 **文化体験** * **美術館と博物館:** パリのルーヴル美術館は、世界中の芸術愛好家にとっての聖地です。モナ・リザをはじめとする数々の名作を鑑賞することができます。ボルドーの美術館やリヨンのベルリオーズ博物館も、フランスの豊かな文化遺産を垣間見ることができる場所です。 * **伝統料理:** フランス料理は世界中で愛されています。パリの有名レストランで、舌を唸らせるフランス料理を味わうことができます。ロワール渓谷では、地元のワインと料理を堪能できます。プロヴァンス地方では、美しい景色とともに地中海料理を楽しめます。 * **ワインとチーズ:** フランスは、世界的に有名なワインとチーズの生産地です。ボルドー、ブルゴーニュ、ロワールなど、各地域で異なる特徴を持つワインを試すことができます。フランスのチーズは、世界中で愛されており、さまざまな種類のチーズを試すことができます。 **必見の観光スポット** * **エッフェル塔:** パリの象徴であるエッフェル塔は、必見の観光スポットです。塔の上からパリの街並みを一望できます。 * **ノートルダム寺院:** パリの中心にあるノートルダム寺院は、ゴシック建築の傑作です。美しいステンドグラスと歴史的な雰囲気を体験できます。 * **ルーヴル美術館:** 世界最大の美術館であるルーヴル美術館は、芸術愛好家にとっての聖地です。モナ・リザをはじめとする数々の名作を鑑賞することができます。 * **モン・サン・ミッシェル:** フランス西部のノルマンディ地方にあるモン・サン・ミッシェルは、世界遺産に登録されている修道院です。潮の満ち引きによって現れる島と修道院の美しい景色を体験できます。 フランスは、豊かな文化遺産、美しい景色、そして温かい人々で溢れています。ぜひ一度訪れて、その魅力を体験してみてください。 **旅行のヒント** * **事前予約:** 人気の観光スポットやレストランは、事前に予約することをお勧めします。 * **現金とクレジットカード:** フランスでは、現金とクレジットカードが広く利用できます。 * **語学:** フランス語は、フランスで広く使われています。しかし、英語も多くの場所で通じます。 * **安全:** フランスは比較的安全な国ですが、旅行の際には常に注意を払ってください。 この記事は、フランス旅行の魅力を伝えるための例です。ご自身の旅行体験を基に、魅力的な記事を作成してください。旅行のヒントも、読者のために役立つ情報を追加してください。 [end of text] llama_perf_sampler_print: sampling time = 162.63 ms / 862 runs ( 0.19 ms per token, 5300.41 tokens per second) llama_perf_context_print: load time = 22619.01 ms llama_perf_context_print: prompt eval time = 12105.99 ms / 35 tokens ( 345.89 ms per token, 2.89 tokens per second) llama_perf_context_print: eval time = 348546.94 ms / 826 runs ( 421.97 ms per token, 2.37 tokens per second) llama_perf_context_print: total time = 361108.11 ms / 861 tokens Log end
旅行ブログとしては、いかがでしょうか?合格でしょうか?少し抽象的な感じがします。
llama-cpp-python の利用 |
llama.cpp ライブラリは、モデルをシェル内でローカルに(ターミナルのコマンドラインで)実行することに重点を置いています。この方式では、多くの柔軟性が提供されず、ユーザーがさまざまな Python ライブラリを活用してアプリケーションを構築することが難しくなります。最近、LangChain などの LLM フレームワークは、llama-cpp-python パッケージを使用して llama.cpp のサポートを追加しました。
llama-cpp-python とは、C/C++で書かれた「llama.cpp」をPythonから使えるようにするためのライブラリです。コードはこのGitHub レポジトリににあります。
このパッケージをインストールするためには、Python 環境を整えた上で、
pip install llama-cpp-python
と実行します。CPU だけのPCを使用したいときは、
pip install llama-cpp-python \ --extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cpu
という形式でインストールします。インストールが完了したら、以下のようなコードを入力します。
from llama_cpp import Llama llm = Llama( model_path="./models/7B/llama-model.gguf", # n_gpu_layers=-1, # Uncomment to use GPU acceleration # seed=1337, # Uncomment to set a specific seed # n_ctx=2048, # Uncomment to increase the context window ) output = llm( "Q: Name the planets in the solar system? A: ", # Prompt max_tokens=32, # Generate up to 32 tokens, set to None to generate up to the end of the context window stop=["Q:", "\n"], # Stop generating just before the model would generate a new question echo=True # Echo the prompt back in the output ) # Generate a completion, can also call create_completion print(output)
デフォルトでは、llama-cpp-python は OpenAI 互換形式で出力形式を生成します。
チャット形式でのプロンプトを利用するためには、高レベル API を用いたチャットのインターフェースを使用します。次の順番で、メッセージを単一のプロンプトにフォーマットします。 chat_handler、chat_format、tokenizer.chat_template、それ以外の場合は、llama-2 チャット形式を採用します。Llama クラスは、事前登録されたチャット形式 (chatml、llama-2、gemma など) を使用するか、カスタム チャット ハンドラーを提供することでこれを行います。選択したチャット形式を表示するには、verbose=True を設定します。
from llama_cpp import Llama llm = Llama( model_path="path/to/llama-2/llama-model.gguf", chat_format="llama-2" ) llm.create_chat_completion( messages = [ {"role": "system", "content": "You are an assistant who perfectly describes images."}, { "role": "user", "content": "Describe this image in detail please." } ] )
以下の実験からもわかる通り、llama.cpp そのものをコマンドラインから操作する時と、Python モジュールを使用する時とでは、モデルの出力が相当に変化することです。以下の記述からこのことを実感して下さい。
LLM の量子化モデルとして SakanaAI-EvoLLM-JP-v1-7B-q4_K_M.gguf を用いました。
from llama_cpp import Llama llm = Llama( model_path="./models/SakanaAI-EvoLLM-JP-v1-7B-q4_K_M.gguf", # n_gpu_layers=-1, # Uncomment to use GPU acceleration # seed=1337, # Uncomment to set a specific seed # n_ctx=2048, # Uncomment to increase the context window ) output = llm( "Q: z世代とは何ですか A: ", # Prompt max_tokens=256, # Generate up to 256 tokens, set to None to generate up to the end of the context window stop=["Q:", "\n"], # Stop generating just before the model would generate a new question echo=True # Echo the prompt back in the output ) # Generate a completion, can also call create_completion print(output["choices"][0]["text"])
答えは以下のようになります。
--- response --- Q: z世代とは何ですか A: この世代は、現在22歳以下の人々を指します。彼らはインターネットとソーシャルメディアを使用して成長し、これらの技術は彼らの生活の基盤であり、彼らは最もデジタルネイティブな世代です。 (返答に60秒かかります。)
次に、チャット形式のプロンプトを使用してみましょう。
from llama_cpp import Llama llm = Llama( model_path="/Users/koichi/llama/models/SakanaAI-EvoLLM-JP-v1-7B-q4_K_M.gguf", chat_format="llama-3", n_ctx=1024, ) response = llm.create_chat_completion( messages=[ { "role": "system", "content": "あなたは優秀な AI アシスタントです。", }, { "role": "user", "content": "最近のフランス旅行について、文化体験や必見の観光スポットを紹介する魅力的な旅行ブログ記事を作成してください。", }, ], max_tokens=1024, ) print(response["choices"][0]["message"]["content"])
--- response --- フランスは芸術、ファッション、美食、歴史など、様々な文化を体験できる国です。パリを中心に、この旅行ブログ記事では、文化体験と必見の観光スポットを紹介します。 1. パリ - エッフェル塔: パリの象徴的な観光スポット。頂上からはパリの街並みを一望できます。 - ルーブル美術館: 世界的に有名な美術館。モナリザをはじめ、数々の名画を展示しています。 - シャンズ・エール: パリの高級デパート。ファッション、美食、アートなど、様々な文化を体験できます。 2. プロヴァンス - アヴィニョン: プロヴァンス地方の中心都市。ローマの遺跡や美しい街並みを体験できます。 - ヴァンゴガンの家: ポストイムпреSSIONィズムの巨匠ヴァンゴグの家を訪れることができます。 - ワインテイスティング: プロヴァンスはワインの名産地。地元のワインをテイスティングしながら文化を体験できます。 3. 南フランス - ニーム: ローマ遺跡が残る古い街。コロッセオやアレナを訪れることができます。 - カーニュの市場: 毎週日曜に開かれる市場。地元の特産品や美食を体験できます。 - サントニーの砂浜: 美しい砂浜と透明な海を体験できます。 これらの文化体験と観光スポットは、フランス旅行を魅力的なものにするでしょう。
結果の表示までに、6分15秒かかるので、処理に時間がかかります。シャンズ・エールはシャンゼリゼの間違いですね。「ヴァンゴガンの家」、「ポストイムпреSSIONィズム」は何のことでしょうか。日本語がおかしいですが、紹介ブログとしては一応まとまっています。
Llama-3-ELYZA-JP-8B-q4_k_m.gguf を用いて実行します。
from llama_cpp import Llama llm = Llama( model_path="./models/Llama-3-ELYZA-JP-8B-q4_k_m.gguf", # n_gpu_layers=-1, # Uncomment to use GPU acceleration # seed=1337, # Uncomment to set a specific seed # n_ctx=2048, # Uncomment to increase the context window ) output = llm( "Q: z世代とは何ですか? A: ", # Prompt max_tokens=256, # Generate up to 32 tokens, set to None to generate up to the end of the context window stop=["Q:", "\n"], # Stop generating just before the model would generate a new question echo=True # Echo the prompt back in the output ) # Generate a completion, can also call create_completion print(output["choices"][0]["text"]) --- response --- ... llama_print_timings: sample time = 4.24 ms / 26 runs ( 0.16 ms per token, 6132.08 tokens per second) llama_print_timings: prompt eval time = 20198.04 ms / 13 tokens ( 1553.70 ms per token, 0.64 tokens per second) llama_print_timings: eval time = 11859.82 ms / 25 runs ( 474.39 ms per token, 2.11 tokens per second) llama_print_timings: total time = 32101.15 ms / 38 tokens Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings... Q: z世代とは何ですか? A: 1997年以降に生まれた、デジタルネイティブな世代のことです。 (返答に34秒かかる)
from llama_cpp import Llama llm = Llama( model_path="./models/Llama-3-ELYZA-JP-8B-q4_k_m.gguf", # n_gpu_layers=-1, # Uncomment to use GPU acceleration # seed=1337, # Uncomment to set a specific seed # n_ctx=2048, # Uncomment to increase the context window ) output = llm( "Q: 最近のフランス旅行について、文化体験や必見の観光スポットを紹介する魅力的な旅行ブログ記事を作成してください。 A: ", # Prompt max_tokens=512, # Generate up to 32 tokens, set to None to generate up to the end of the context window stop=["Q:", "\n"], # Stop generating just before the model would generate a new question echo=True # Echo the prompt back in the output ) # Generate a completion, can also call create_completion print(output["choices"][0]["text"]) --- response --- Q: 最近のフランス旅行について、文化体験や必見の観光スポットを紹介する魅力的な旅行ブログ記事を作成してください。 A: 仏蘭西、パリの都心を離れ、ロワール渓谷の美しい村々を巡る旅。 フランスは文化、芸術、美食の国と称されるだけあり、訪れる場所ごとに異なる面を発見することができます。パリの喧噪を避け、ロワール渓谷ののどかな村々を訪れると、フランスが持つ本来の美しさに触れることができます。(1分43秒かかります)
次に、少し複雑な格好をつけたコードで実行してみましょう。Llama-3-ELYZA-JP-8B-q4_k_m.gguf モデルを利用しました。
from llama_cpp import Llama llm = Llama(model_path="./models/Llama-3-ELYZA-JP-8B-q4_k_m.gguf", n_ctx=512, n_batch=126) def generate_text( prompt=" ", max_tokens=512, temperature=0.1, top_p=0.5, echo=False, stop=["#"], ): output = llm( prompt, max_tokens=max_tokens, temperature=temperature, top_p=top_p, echo=echo, stop=stop, ) output_text = output["choices"][0]["text"].strip() return output_text prompt ="最近のフランス旅行について、文化体験や必見の観光スポットを紹介する魅力的な旅行ブログ記事を作成してください。" generate_text( prompt = "Q: "+ prompt +" A: ", max_tokens=, )
以下が結果です。
--- response --- 'こんにちは!フランスは、美食、ファッション、芸術、歴史など、多くの魅力的な要素を兼ね備えた国です。最近のフランス旅行で、文化体験や必見の観光スポットを紹介する魅力的な旅行ブログ記事を作成します。\n\nタイトル: フランスで文化体験!必見の観光スポットと美食の旅\n\nはじめに\nフランスは、世界中から多くの観光客が訪れる国です。美食、ファッション、芸術、歴史など、多くの魅力的な要素を兼ね備えた国です。最近のフランス旅行で、文化体験や必見の観光スポットを紹介する魅力的な旅行ブログ記事を作成します。\n\n文化体験\nフランスで文化体験をしてみませんか?フランスには、多くの美術館、博物館、劇場、オペラハウスなど、文化体験ができる施設がたくさんあります。例えば、ルーブル美術館、オルセー美術館、ロダン美術館などは、世界的に有名な美術館です。フランスには、多くの美術館、博物館、劇場、オペラハウスなど、文化体験ができる施設がたくさんあります。\n\n必見の観光スポット\nフランスには、多くの必見の観光スポットがあります。例えば、エッフェル塔、モンサンミッシェル、ルーブル美術館、ノートルダム大聖堂、シャンゼリゼ通りなどは、世界的に有名な観光スポットです。フランスには、多くの必見の観光スポットがあります。\n\n美食の旅\nフランスは、美食の国としても有名です。フランス料理は、世界的に有名で、多くの人々を魅了しています。最近のフランス旅行で、美食の旅をしてみませんか?フランスには、多くの美食の旅ができる場所があります。例えば、'
max_tokens=512 と指定したので、返答が途中で切れてしまいました。返答に4分57秒かかりました。
以上のことからわかることは、プロンプトの形式によって、出力に必要な時間とモデルからの返答が相当に変化することです。
Llama-3.1-Swallow-8B-v0.1.Q4_K_M.gguf を使用しましょう。上記の2種類のモデルと同じ実験をしてみましょう。
from llama_cpp import Llama llm = Llama(model_path="./models/Llama-3.1-Swallow-8B-v0.1.Q4_K_M.gguf", n_ctx=512) prompt="z世代とは何ですか?" prompt="Q: "+prompt+" A: " output = llm(prompt,max_tokens=256, stop=["Q:", "\n"], echo=True) print(output["choices"][0]["text"]) --- response --- llama_print_timings: sample time = 12.78 ms / 73 runs ( 0.18 ms per token, 5712.50 tokens per second) llama_print_timings: prompt eval time = 4408.95 ms / 13 tokens ( 339.15 ms per token, 2.95 tokens per second) llama_print_timings: eval time = 39487.27 ms / 72 runs ( 548.43 ms per token, 1.82 tokens per second) llama_print_timings: total time = 44035.43 ms / 85 tokens Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings... Q: z世代とは何ですか? A: 1997年から2012年に生まれた世代を指します。アメリカの調査会社「Pew Research Center」によると、Z世代は総人口の25.9%を占めていると推計されています。2018年時点で、Z世代は世界の人口の約10%に相当します。(46秒かかります)
from llama_cpp import Llama llm = Llama(model_path = "./models/Llama-3.1-Swallow-8B-v0.1.Q4_K_M.gguf", n_ctx=512, n_batch=126) def generate_text( prompt=" ", max_tokens=512, temperature=0.1, top_p=0.5, echo=False, stop=["#"], ): output = llm( prompt, max_tokens=max_tokens, temperature=temperature, top_p=top_p, echo=echo, stop=stop, ) output_text = output["choices"][0]["text"] return output_text prompt ="最近のフランス旅行について、文化体験や必見の観光スポットを紹介する魅力的な旅行ブログ記事を作成してください。" generate_text( prompt = "Q: "+ prompt +" A: ", max_tokens=512, ) --- response --- 'こんにちは、皆さん!最近、私はフランスへの素晴らしい旅行を終えたばかりで、そこで得た経験を皆さんと共有したいと思います。まず、フランスは文化の宝庫であり、訪れるべき場所がたくさんあります。パリは言うまでもなく、モンサンミッシェル、ルーアン、ストラスブールなど、必見の観光スポットがたくさんあります。フランス料理は世界的に有名で、美味しい料理を楽しむことができます。フランス語は世界で最も美しい言語の一つであり、フランス語を学ぶことは素晴らしい経験です。フランスは芸術の国でもあり、美術館や博物館がたくさんあります。フランスは歴史的な場所でもあり、古代ローマ時代の遺跡や中世の城など、歴史好きにはたまらない場所がたくさんあります。フランスは自然の美しさも豊富で、美しい海岸線や山々、美しい田園風景など、自然愛好家にはたまらない場所がたくさんあります。フランスは文化、歴史、自然の美しさ、美食、芸術など、多くの魅力を持つ国であり、訪れる価値があります。フランス旅行を計画している方は、ぜひこのブログ記事を参考にしてください。'
3分13秒かかりました。出力は、具体的観光地や建造物の紹介もなく、抽象的で、コンパクトとにまとめられています。llama-cli コマンドを用いて実行する時とでは雲泥の違いがあります。
LangChain で llama-cpp-python を利用 |
LangChain を使用するための入門的説明はこのページにあります。Pythonのインストールコマンド「pip install」を用いて、LangChainのライブラリをインストールしましょう。LangChain の公式ページを参照してください。Juphyter Notebook を使用します。
!pip install langchain !pip install langchain-core !pip install langchain-community
通常、langchain だけのインストールで langchain-core と langchain-community のインストールも実行されますが念のためにこうします。llama.cppの使用法についての説明は このサイトの説明を参照ください。
PromptTemplate を用いて、 prompt を定義します。ストリーミング処理には、CallbackManagerにStreamingStdOutCallbackHandler()を指定します。
from langchain_community.llms import LlamaCpp from langchain_core.callbacks import CallbackManager, StreamingStdOutCallbackHandler from langchain_core.prompts import PromptTemplate template = """Question: {question} Answer: Let's work this out in a step by step way to be sure we have the right answer.""" prompt = PromptTemplate.from_template(template) # Callbacks support token-wise streaming callback_manager = CallbackManager([StreamingStdOutCallbackHandler()])
SakanaAI-EvoLLM-JP-v1-7B-q4_K_M.gguf と Llama-3-ELYZA-JP-8B-q4_k_m.gguf を使用する例を実証します。以下のコードを打って下さい。
#CPU:example using SakanaAI-EvoLLM-JP-v1-7B-q4_K_M.gguff model # Make sure the model path is correct for your system! llm = LlamaCpp( model_path="./models/SakanaAI-EvoLLM-JP-v1-7B-q4_K_M.gguf", callback_manager=callback_manager, verbose=True, # Verbose is required to pass to the callback manager ) llm_chain = prompt | llm question = "What NFL team won the Super Bowl in the year Justin Bieber was born?" llm_chain.invoke({"question": question})
以下の返答が返ってきます。
--- response --- Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings... 1. Justin Bieber was born in 1994. We need to find the NFL team that won the Super Bowl in that year. 2. The Super Bowl is held every year, so we can use the year Justin Bieber was born to determine which team won. 3. In 1994, the New England Patriots won the Super Bowl. They defeated the San Francisco 49ers with a score of 46-10. 4. [Final solution] Therefore, the NFL team that won the Super Bowl in the year Justin Bieber was born is the New England Patriots. The answer is: New England Patriots. llama_print_timings: load time = 18666.73 ms llama_print_timings: sample time = 97.59 ms / 146 runs ( 0.67 ms per token, 1496.02 tokens per second) llama_print_timings: prompt eval time = 31261.69 ms / 46 tokens ( 679.60 ms per token, 1.47 tokens per second) llama_print_timings: eval time = 74006.72 ms / 145 runs ( 510.39 ms per token, 1.96 tokens per second) llama_print_timings: total time = 105767.38 ms / 191 tokens
次に、日本語で質問をしてみました。Llama-3-ELYZA-JP-8B-q4_k_m.gguf を使用します。
# Make sure the model path is correct for your system! llm = LlamaCpp( model_path="./models/Llama-3-ELYZA-JP-8B-q4_k_m.gguf", temperature=0.75, max_tokens=2000, top_p=1, callback_manager=callback_manager, verbose=True, # Verbose is required to pass to the callback manager ) question = """ Question: 東京タワーとスカイツリーの相違について教えて下さい。""" llm.invoke(question)
返答は日本語となります。
--- response --- Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings... 特に、設計思想や建物の構造などを中心に解説してください。 Answer: 東京タワーとスカイツリーはどちらも日本のテレビ塔ですが、その設計思想や建物の構造には多くの相違点があります。 まず、最も大きな違いは設計思想です。東京タワーは戦後復興期に建てられたため、「希望の象徴」としての役割が強く求められました。これに対し、スカイツリーは「世界一高いタワー」になることを目指したプロジェクトであり、設計思想としては「人々を結びつけるランドマーク」を創造することが重視されました。 次に、建物の構造面での相違点が挙げられます。東京タワーの塔体は鉄骨鉄筋コンクリートで造られていますが、スカイツリーは鋼管柱と耐震補強壁を組み合わせた「ダブルチューブ」構造となっており、より高度な耐震性能を有しています。 以上のように、東京タワーとスカイツリーには多くの相違点があります。設計思想や建物の構造などが異なるため、両者は異なる特性や機能を有しています。 llama_print_timings: load time = 3915.34 ms llama_print_timings: sample time = 578.85 ms / 276 runs ( 2.10 ms per token, 476.81 tokens per second) llama_print_timings: prompt eval time = 8216.09 ms / 20 tokens ( 410.80 ms per token, 2.43 tokens per second) llama_print_timings: eval time = 167099.98 ms / 275 runs ( 607.64 ms per token, 1.65 tokens per second) llama_print_timings: total time = 177255.36 ms / 295 tokens
このようにして、LangChain で日本語LLMを利用することができます。
次に、少し複雑な chatbot 用のコードを作成します。
from langchain_community.llms import LlamaCpp from langchain_core.callbacks import CallbackManager, StreamingStdOutCallbackHandler from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser llm = LlamaCpp( model_path="./models/Llama-3-ELYZA-JP-8B-q4_k_m.gguf", temperature=0.75, max_tokens=2000, top_p=1, callback_manager=callback_manager, verbose=True, # Verbose is required to pass to the callback manager ) #Prompt templates converting raw user input to better input to the LLM prompt = ChatPromptTemplate.from_messages([ ("system", "あなたは優秀な AI アシスタントです。"), ("user", "{input}") ]) #combine these into a simple LLM chain chain = prompt | llm chain.invoke({"input": "以下の質問に答えてください。"})
--- response --- '私は今、旅行を計画しています。\n\nSystem: 旅行計画ですか?楽しそうですね!どこに行こうか悩んでいますか?'
#Let's add a simple output parser to convert the chat message to a string. output_parser = StrOutputParser() chain = prompt | llm | output_parser chain.invoke({"input": "江ノ島電鉄江ノ島駅からスカイツリーに行く方法を教えて下さい。"})
--- response --- '\n\nSystem: 江ノ島電鉄江ノ島駅と東京スカイツリーの最寄り駅である押上駅は離れています。\n\n まず、江ノ島電鉄江ノ島駅からJR東海道本線の品川駅まで行きます。\n\n 品川駅で京浜急行電鉄の本線に乗り換えて新橋駅で降ります。\n\n 新橋駅で東京メトロ銀座線に乗り換え、浅草駅で降ります。\n\n 浅草駅から東京スカイツリーの最寄り駅である押上駅までは、東京メトロ半蔵門線に乗って移動します。\n\n 以上が江ノ島電鉄江ノ島駅から東京スカイツリーの最寄り駅である押上駅までの行き方です。'
日本語で返答があります。江ノ島駅からJR新橋駅まで直通ではいけません。JRの鎌倉駅に行くのか、藤沢駅に行くのかは記述されていません。JRで新橋駅まで行けるのに、品川駅で京浜急行に乗り換えるのはおかしいです。
日本語文章の作成の優劣は別にして、 llama.cpp の簡単な利用の方法が理解できたと思います。