charlm-agent

5000 万パラメータ(52.6M)の文字単位の小さな言語モデルです。2 つのことができます。

  1. 役になりきった会話:短い人物設定(カード)を渡すと、その人物として雑談や簡単な案内に答えます。
  2. ゲームの行動選び:ゲームが「目標・状態・使える操作」を送ると、目標に近づく操作をタグで返します。

CPU だけで動きます。4bit 版は 33MB です。

どれを使えばいいか

フォルダ 中身 使いどころ
agent13b/ 会話 + 行動選び(最新)。agent12a に、教師モデルに「口調がどうあれ事実は正確に」と指示して書かせた会話 3,600 本(ダークファンタジー・友達ゲーム多め)を追加学習。名前の記憶やお店の時間などの事実の正答 80 → 85%、ダークファンタジーでの名前の記憶 23 → 57%、嫌いな贈り物への反応 54 → 69% 迷ったらこれ
agent12a/ 1 つ前の版(agent11 が自分で作った返答の良いものだけで追加学習) 比較用
agent11/ 1 つ前の版 比較用
agent6/ 2 つ前の版 比較用
npc4/ 会話だけに絞った版 行動選びが要らず、会話の質を優先したいとき
base/ 事前学習だけの土台 自分で追加学習したいとき

各フォルダの model_final.pt は通常版(210MB)、model_4bit.pt は 4bit 量子化版(33MB)です。

使い方

charlm_run.py と charlm_fold.py を同じ場所に置いて使います(PyTorch のみ必要)。

from charlm_run import Model
m = Model("agent13b/model_4bit.pt")          # GPU があれば GPU、なければ CPU

# 会話: 最初のユーザー発話の前にカードを置き、空行で区切る
card = "You are Mira, a farmer in the village of Elm. You are cheerful and practical."
print(m.reply([card + "\n\nHi! What do you grow here?"], temp=0.7))

# 行動選び: GOAL / OPS / STATE を毎ターン送る。答えは {考えの筋道}<操作>
turn = ("GOAL: life >= 1\n"
        "OPS: <a> life+1 gold-3 | <b> gold+2 (needs gold>=1) | <c> life-1\n"
        "STATE: life=0 gold=7")
print(m.reply([turn], n=260))              # -> {life 0 >=1 up. up: a+1. a ok}<a>

reply(turns) の turns は、ユーザー → モデル → ユーザー … の順に並べた文字列のリストです。

行動選びの形式

  • GOAL: 変数 比較 数:達成すべき条件(>= <= > < ==、and で 2 つまで)
  • OPS: <名前> 変数+数 変数-数 (needs 変数>=数) | ...:使える操作。名前は自由(学習で見ていない名前でも読めます)
  • STATE: 変数=数 ...:今の状態。目標の変数を先頭に置くのが約束事です(agent11 は他の順番でもほぼ同じように読めます)
  • 答えの最後の <名前> を実行し、新しい STATE を送る。目標を満たすと <none> が返ります

ゲームに組み込むときのコツ

  • 目標は 1 つずつ渡す。「道具を作ってから売る」のような段取りはゲーム側で小目標に分けると、ほぼ確実に動きます。
  • 使えない操作は一覧から外す。返ってきたタグがおかしければ、その操作を外して聞き直す。
  • 例:village.py(3 人の村人が市場を共有して暮らすシミュレーション)。小目標に分けた形で、4 日間・48 回の判断でゲームに弾かれた回数は 0、全員が所持金を増やしました。

成績(agent13b、4bit)

行動選び:学習で見ていない作り物の名前で、ゲームとやり取りしながら目標に届いた割合(各 100 問、目標の変数が先頭 / 並び順ばらばら)。

レベル 内容 agent13b
1 目標 1 つ 99 / 99%
2 関係ない操作・前提条件が混ざる 93 / 92%
3 先に前提を満たしてから使う(2 段) 85 / 81%
4 目標 2 つ、片方を壊さない 81 / 76%

住人テスト(3 種類のゲームの住人 128 人、学習で見ていない設定、1,544 問):名前を覚える・お店の時間などの事実の正答 85%(agent12a 80%、agent11 74%、agent6 78%)、採点役(Qwen3.5-4B)が「使える」とした返答 90%、ルール違反なし 96.5%(名前を忘れた 20 問、agent12a は 33 問)。ジャンル別の事実の正答:どうぶつの森風 96%、友達ゲーム風 87%、ダークファンタジー風 57%(agent12a は 23%)。同じ重みを 2 回採点すると事実の正答は ±8 ポイントぶれるので、それより小さな差は意味がありません。

会話の予測誤差(1 文字あたり、通常版、小さいほど良い):日常会話 0.827、NPC 0.730、案内 0.912、住民 1.075(agent12a は 0.822 / 0.724 / 0.909 / 1.094、agent6 は住人 1.37)。雑談の力は落ちていません。

作り方

  • base/:WikiText-103 と FineWeb-Edu を 63 億文字学習(16 層、幅 512、文脈 4096 文字、文字の種類 100)。
  • 会話:SmolTalk、SODA(人物設定つきの会話)、Qwen3.5/3.6 で作った NPC 会話と案内データで追加学習(npc4/)。
  • 行動選び:ルールで作った目標達成の会話(考えの筋道つき)を雑談と半々に混ぜて追加学習(agent6/)。

学習データの出典と利用条件:WikiText-103(CC BY-SA)、FineWeb-Edu(ODC-By)、SmolTalk(Apache 2.0)、SODA(CC BY 4.0)、Qwen3.5/3.6(Apache 2.0)の生成データ。

限界

agent13b は事実を正しく言う代わりに、お店の時間を聞かれたときの答えが「It opens at 8 am and closes at 5 pm.」のように素っ気なくなることがあります(採点役はこれを「役になりきれていない」と減点します)。

小さなモデルなので、短いあいさつ、天気、プレゼントへの反応、お店の時間のような単純なやり取りは得意ですが、相談に乗るような開いた質問や、長い文になるとつじつまが合わなくなります。ダークファンタジーの住人は、名乗った名前を覚えていないことが多いです。返答をいくつか作って talk_rules.py(GitHub)で壊れたものを落とすと安定します。行動選びでは、3 段以上の段取りや、操作がどの値に効くかの読み違い、数の大小の判断ミスが残っています。

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support