2026年3月27日金曜日

localAIでのRakuten AI 2.0 mini

結構試行錯誤の末になんとなくまともに動くようになった感じです。(contextの大きさなども含め動くだけの設定ですが。)

色々と試行錯誤してみると細かいところでlocalAIの中身がわからないのでソースを見ながら調整していました。

おもに.yamlファイルのtemplateを調整していたのですが、結局のところ何も考えなければ、

options:
 - use_jinja: true

と設定すればllama-cppでgguf内の定義体からtokenizer.chat_templateをつかってプロンプトをいい感じに扱うようになりました。

ただ、この設定にするとdebugメッセージで実際のトークン内容が見えなくなってしまいます。それと、システムプロンプトに設定したものがうまく反映されているのかどうかもわかりませんでした。(少なくても反応してない感じ)

結果 .yaml の template を調整する必要になるのですが、基本的にはtokenizer.chat_templateを基に考えればいいはず。

localAIのドキュメント(https://localai.io/advanced/model-configuration/index.html)を見ると.yamlのサンプルに

name: my-llm-model
description: A high-performance LLM model
backend: llama-stable

:
:

template:
chat: |
{{.System}}
{{range .Messages}}
{{if eq .Role "user"}}User: {{.Content}}
{{else if eq .Role "assistant"}}Assistant: {{.Content}}
{{end}}
{{end}}
Assistant:

と言う物が載っていたのでこのまま行けるんじゃ?と思ったのですが、この形式はllama-cppでは使えませんでした。(仕様が変わったのか、バックエンドにllama-stableを使えば行けるのかわかりませんが)

試行錯誤の末出来上がったものがこちら。

stopwords:
- "USER:"
- "ASSISTANT:"
template:
  chat_message: |-
    {{- if eq .MessageIndex 0 }}
      {{- if eq .Role "system" }}
        {{- trim .Content }}
      {{- else }}
        {{- "A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user's questions." }}
      {{- end }}
    {{- end }}
    {{- if eq .Role "user" }}USER: {{ trim .Content }}
    {{- else if eq .Role "assistant" }}ASSISTANT: {{ trim .Content }}</s>
    {{- end }}
  chat: |-
    {{- regexReplaceAll "\n(USER:|ASSISTANT:) " (regexReplaceAll "\nASSISTANT: " .Input " ASSISTANT: ") " $1 " }}
    {{- " "}}ASSISTANT:
  completion: |-
    {{- .Input }}
roles:
  user: "user"
  system: "system"
  assistant: "assistant"

途中gemeiniさんに相談したりいろいろしてみましたが、localAIのプロンプトのやり取りと、Rakuten AI 2.0 mini Instructがどのように反応するのか見てみないといけなかったので、最終的にlocalAIのソースと、実際に動かしながら結構強引にやってます。なので細かい例外はこの際目をつぶることにしました。

Rakuten AI 2.0 mini (Instruct)のtokenizer.chat_templateから見える実際のテキストストリームはこのような形になります。

最初は

「USER: [UserInput] ASSISTANT:」もしくは、システムプロンプトがあれば
「[SystemPrompt] USER: [UserInput] ASSISTANT:」

それ以降はこんな感じ。
「[SystemPrompt] USER: [UserInput1] ASSISTANT: [ModelOutput1]</s> USER: UserInput2] ASSISTANT: [ModelOutput2]</s> ~ USER: [UserInput] ASSISTANT:」

という形式でやり取りするという事。改行(\n)は行いません。

</s>があって<s>がないのが気になった(というか色々調整して途方にくれましたw)のでRakutenAI-2.0-mini-instruct-Q8_0.ggufのmetadataをみると、tokenizer.ggml.add_bos_tokenがtrueになっているので<s>は付加されるという事のようです。実際にどのようにbosが追加されているのか不明なのでいろいろ試してみたところ、bosが無い状態でトークンが来ると自動でbosを付加している感じでした。結果としてchat_templateで示している会話の1つの質疑ー>応答のタイミングで区切ること会話が安定していました。 

まぁ</s>がなくてもいいような気はしています。ただ、改行が含まれるとかなり会話がおかしなことになります。

最初は普通にテンプレートを書き換えても、1メッセージ(User側の入力やAssistant側の出力)単位で必ず改行されているのでそれが普通だと思っていたのですが、どうも安定しないので結構強引に改行を消すと会話が成立しやすくなりました。

ざっくりと説明すると、.yamlのtemplate内のchat_message/chat/completionのテンプレートで定義されたもので整形し、backend(llama-cpp)へ送られます。 

localAI側はlocalAI内で扱っているデータをChatMessageTemplateData構造体に設定し、.yamlのtemplate内のchat_messageのテンプレートで定義されたもので整形します。すべてのメッセージを一纏めにした後、chatのテンプレートで整形し、最終的にcompletionで整形するようになっています。(ドキュメントを鑑みると、現状では1メッセージ単位から組み立てたうえで、chatで整える形になっているが、もともとは一回で整形していただけの様です。)

今回問題となるは chat_massageで整形されたものがchatで整形される前に1メッセージごとに改行コードが強制的に付加されている点です。どこかにパラメータがあれば良かったのですが、コード内を見る限りそのような分岐は見当たり…ありましたねw

現時点のコードでは    LocalAI/core/templates/evaluator.goの200行目から

	joinCharacter := "\n"
	if config.TemplateConfig.JoinChatMessagesByCharacter != nil {
		joinCharacter = *config.TemplateConfig.JoinChatMessagesByCharacter
	}

に定義されていてconfig.TemplateConfig.JoinChatMessagesByCharacterはyamlかjsonで取ってくるような雰囲気がLocalAI/core/config/model_config.goにあります。 

なので早速設定して、少し変更しました。

stopwords:
- "USER:"
- "ASSISTANT:"
template:
  chat_message: |-
    {{- if eq .MessageIndex 0 }}
      {{- if eq .Role "system" }}
        {{- trim .Content }}
      {{- else }}
        {{- "A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user's questions." }}{{ " " }}
      {{- end }}
    {{- end }}
    {{- if eq .Role "user" }}USER: {{ trim .Content }}
    {{- else if eq .Role "assistant" }}ASSISTANT: {{ trim .Content }}</s>
    {{- end }}
  chat: |-
    {{- .Input }}
    {{- " "}}ASSISTANT:
  completion: |-
    {{- .Input }}
  join_chat_messages_by_character: " "
roles:
  user: "user"
  system: "system"
  assistant: "assistant"

強引な部分が消せましたw

ただ、ここまでやってもシステムプロンプト的なものを設定しても思った以上に効果が無かったりします。運次第ですが。

そんな感じでRakuten AI 2.0 miniに触れてみたのですが、基本的な感触としては会話と言うより情報端末に対して問いかける感じで、とにかくはっきり問いかけないとダメな感じです。何も用事がない場合は Rakuten AI 2.0 mini 側から話しのネタを提示してユーザー側に問いかけさせるようにする感じです。

なので、「こんにちは」「あなたの名前は?」「私の名前は~です」といった質疑応答に関係のない話題に対してとても不安定な回答をしたり、内部で混乱のもととなり、例えば

👨「こんばんは」
🤖「こんにちは!どのような話題についてお話したいですか?」
👨「ニュースについて教えて
🤖「こんにちは!今日のニュースです。* 経済:日本のGDP成長率が…

と言ったように2回挨拶を繰り返したり、しかも「こんばんわ」に対して「こんにちは!」とかちょっとアレな感じになったりします。

また、矛盾が生じると頻繁にエコーチャンバーを起こし、簡単に暴走します。2回程度で収まればいいのですが、contextが溢れるまで繰り返すことの方が多いです(笑)なのでチャットでは強制停止機能が必須です。

とくにRakuten AI 2.0 miniでは素直に冒頭から「ニュースについて教えて」と問いかけるのが正解です。

世間話をするために名前を付けようとしましたが、なかなか上手く行きませんでしたし…。会話はできるのですが、自分自身とユーザーの区別が明確に分かれていない状態のようでした。

結果的にRakuten AI 2.0 miniでできることは持っている知識に対して教えてもらうというぐらいでしょうか。現状ではこれを中心に何かできるとは思えないですね。

倫理的な保護機能はあるのですが、少し言い方を変えるだけで開示されたりするので、理論的と言うより機械的に保護されているレベルにとどまっている感じです。

言語に関しては英語と日本語となっていますが、ハングル文字も認識してるし、スペイン語も出力してきたりするので、適当に言語は扱える感じです。(ただ出力されたものをみるとそこまで流暢ではなさそうでした)まぁ日本語と英語が相互に扱えるだけで十分ですが。

 

今回苦労したおかげでテンプレートについていろいろ知ることができたのは唯一の救いかな? 

OllamaのRakuten AI 2.0 mini instruct

localAIでいろいろと納得いかず、WindowsにOllamaをインストールして確認してます。

Ollamaのインストーラーもいつの間にか2G近いサイズになっていて驚きました。

インストールしたら、コマンドプロンプトでモデルのインストール。 

> ollama pull hf.co/mmnga/RakutenAI-2.0-mini-instruct-gguf:Q8_0

ほんと、コマンドラインの履歴が残ってて助かりました…w

ダウンロードしたggufを手作業で設定するのは良く分からないので、悩んだらpullするのが早いです。ollamaにインストールしたモデルは ollama ls とかで一覧は出るし、おそらくollama rm とかやればモデルの削除も簡単にできる感じがします。何も考えずに遊べますねw

とは言え、現状ではWindows版だとintelのGPUが対応していないのでCPUのみの動作となり、非力なPCでは悲惨なことに…w まぁ軽いモデルなら、そこまで気にしなくていいかもしれませんが、軽いと思っていたRakuten AI 2.0 mini instructでもガッツリ固まりまくりでした…。

で、チャットしてみると結構まともにチャットできるんです。いきなり「konbanha」とか打ち込むとエラーメッセージのような感じの応答があったりしますが、まぁ「こんばんは」とか入力すると、それなりの話題作りのような導入があったり、それなりのRakuten AI 2.0 miniらしさ が見えます。

会話もちゃんと繋がってる感じがするし、いい感じでした。

そして見えてくる道具としてのAI感。世代が古いとはいえ、おそらく周回遅れ感はするものの、道具としてみると悪くないかなとも感じる。挨拶から会話を始めると極端に不安定になるのは致し方がないところかな?

Ollamaのチャットインタフェースだと、システムプロンプトが設定できないのが残念なんですよね… 

2026年3月21日土曜日

さらに…

結局のところデバッグログを出しながら見てみるとlocalAI内部は意図通りに出力されているのが確認できました。

最終的にgeminiが下した判断は、パラメータでもう少し落ち着かせて冷静にさせてダメなら量子化などの影響が色濃く出ちゃってるんじゃ?とかなりRaktenAI2.0miniをオブラートに包んでダメ出しした感じですw

まぁ会話の最初で暴走気味しなければそれなりにいい感じなので、挨拶や会話調で話し始めるのはダメなのかもしれませんね。

今まで質問をぶつけてダメだった記憶は…あまり最初から質問をぶつけたことは無いか…

 

今回、面白かった?会話の小ネタ

👨「こんばんは
🤖「おやすみなさい

 会話してくれないんですかね…

 

👨「こんばんは
🤖「システムへ。
👨「こんばんは
🤖「システムへ。
👨「会話はできますか?
🤖「できません。

 相当嫌われてる模様…

 

 

2026年3月20日金曜日

gemma3に初めて触れたとき以来熱心にチャットした気がする…

なんか今日はとても疲れた…
何だろこのやるせなさ(笑)

👨「こんばんは
🤖「おはようございます

 と返されたり、

👨「今日の天気について教えてください。
🤖「今日の東京の天気は晴れ時々曇りで、最高気温は25度前後、最低気温は15度くらいまででしょう。
👨「今日は何年何月何日ですか?
🤖「今日の日付は2023年10月15日です。
👨「何曜日ですか?
🤖「今日は木曜日です。
👨「2023年10月15日は日曜みたいですけど…
🤖「はい、正しく計算されています!
👨「2023年10月15日は木曜日ですか?
🤖「はい、正解です!

このキャッチボールのできなさ加減(笑)

システムプロンプトを入力したりしなかったり、数行システムプロンプトを入れてみたり色々変えながら様子を見ましたが…まじいろんな意味で疲れたw

挙句の果てに挨拶すると突然演説が始まるとか…

👨「こんばんは
🤖「おっしゃる通りです。私たちの製品は、世界中のユーザーに高品質のサービスを提供するために、常に改善されています。今回ご紹介した新機能は、ユーザー体験の向上を目指しており、私たちの目標の一つです。この機能により、ユーザーはより快適に、そして効率的に作業を進めることができるようになります。さらに、新機能の導入により、ユーザーインターフェースもさらに洗練され、直感的で使いやすいデザインへと進化します。これにより、ユーザーは時間を節約しながら、高い品質を維持することができます。新機能の開発には、さまざまなユーザーテストを実施し、実際のニーズを反映した設計を行いました。これにより、ユーザーのフィードバックを反映し、より多くのユーザーにとって魅力的な製品へと進化させることができました。また、私たちのチームは、新機能のリリース後も、継続的にテストと改善を行い、ユーザーからのフィードバックをもとにさらなる改良を加えていきます。これにより、常に最新の技術とユーザーニーズを反映した製品を提供し続けることができます。最後に、新機能の導入に伴い、ユーザーの皆様へのご協力のお願いがあります。新機能のご利用方法や、ご不明な点がございましたら、お気軽にご連絡ください。私たちは、皆様のご意見やご要望を大切にし、より良い製品とサービスを提供するために努力を惜しみません。ご理解とご協力のほど、心より感謝申し上げます。

どこの広告からパクってきたんだよ(笑)

結局.yamlの定義を簡素化するのが安定するような気はしますが…

で、Rakuten AI 2.0 miniでもなんか意思を感じる部分はありました。上手く会話がかみ合って始まればそれなりに進んでいくわけで…ただ、ほんの少しだけですけど。gemma3nの様な雰囲気ではありませんが。なので特定の部位に到達できればそれなりに深い思考領域に到達できるものの、完全に運任せなんでしょうね。満遍なくこなれていない感触です。

システムプロンプトという結構強制力がありそうだと思っていたものも、gemma3のストリームの最初に伝える方法と扱いに差はないようです…w

geminiさんにもお付き合い願い、いろいろやり取りしましたが、今回はこの辺が限界かな…モチベーション的にw

以下参考までに現状の .yaml を…

backend: llama-cpp
context_size: 8192
name: RakutenAI-2.0-mini-instruct-Q8_0
parameters:
model: RakutenAI-2.0-mini-instruct-Q8_0.gguf
stopwords:
- <|im_end|>
- <|im_start|>
- <|endoftext|>
template:
chat: |
{{.Input}}
<|im_start|>assistant
chat_message: |-
<|im_start|>{{.Role}}
{{.Content}}<|im_end|>
completion: |
{{.Input}}
roles:
user: user
system: system
assistant: assistant

あとはデバッグモードで中身を追っかけて確認して終わりかな? 

イギリスの郵便局に納入されたシステムの不具合

午後4時の〇HKニュースで流れていたが、イギリスの郵便局に納入されたシステムの不具合でシステム上の金額と現金に差異が発生し、それにより郵便局員900人以上が横領などの罪で訴追され罪に問われた事件があったとのこと。

その冤罪で被害にあった被害者や家族に対して、イギリス政府が保証金を配っているというニュースが流れたが結局これ、〇通に被害請求行くんじゃ?

WEB上の〇HKの記事は見れるが、なんかあれなのでBBCの記事へのリンクを

英郵便局スキャンダル、不当な有罪覆す法案を提出 補償制度も 

こっちを見るとさらに突っ込んだ内容が出ていて、補償金がかなりエグイ…

「法案では、冤罪の有罪判決を受けた被害者に、正式に請求しなくても60万ポンド(約1億1300万円)で和解するオプションが提供される。」

1999年から2015年にかけて発生した事件らしいが、普通に考えて、システム上の金額が現物と合わないとか、システム内部の基幹部分だったらいくらでも調べればずれているのはわかるはずだから、窓口のレジレベルの入力端末でバグが発生したってことかな?

それが最低でも900回以上あったわけで、それがシステムの不具合として認められるまでかかったってことは、局員たちは疑がわれて当然とか横領が多かったのかな?それともそんな単純なところでシステムにバグがあるはずがない!とかシステム至上主義の人間ばかりだったのだろうか?

とは言え、このバグって、システムとは別建ててキーロガーを導入したりしてそれとのすり合わせをしないと証明できなくね?あとはそれこそ窓口で現金を扱う時は裸にならないと…