JapaneseTinyAgentLM Action 3M
日本語の短い依頼文を、ロボットの動作呼び出し(JSON)に変える、パラメータ数 3,148,608 の小さな言語モデルです。M5Stack のスタックチャン(CoreS3、ESP32-S3)の本体だけで動かすために、一から学習しました。NPU、外付けのモジュール、ネットワークは使いません。
入力: 顔を右に45度向いて
出力: [{"name":"look","arguments":{"direction":"right","degrees":45}}]
入力: LEDライトの色を青にして
出力: [{"name":"set_led","arguments":{"color":"blue"}}]
コード(学習、評価、C の runtime、firmware): GitHub(Apache-2.0)
ブラウザで試す: デモ(Hugging Face Space)。インストール不要で、実機と同じ C の runtime(WebAssembly)と INT4 の重みがブラウザの中で動きます。
English summary at the end.
この版は Action schema v1 のデータ v1.1 です(2026年10月)。 首の向きを角度でも指定でき、相対の移動、斜め、首振り、お辞儀、表情 7種類、LED の色、音量、画面の明るさを扱います。v1.1 では、色を言わずに LED を点ける依頼(「ライトをつけて」「LEDを点灯して」など)を白で点けるようにしました。v1.0 はこれを何もしないか、消灯と読んでいました。前の版(schema v0。
look、set_expression、nodの3つだけ)は、このリポジトリの commit 履歴に残っています。v0 と v1 では tokenizer が違うので、.jtlmと firmware は同じ版のものを組み合わせてください(下の「スタックチャンで動かす」)。
できること
出力は、次の 11 の動作を最大2個まで並べた JSON の配列です(action_schema_v1.json)。動作の依頼でない文、否定された依頼、このロボットにない機器への依頼(「寝室のライトをつけて」「エアコンを25度に」など)、このロボットにはできない依頼には [](何もしない)を返します。
| 動作 | 引数 |
|---|---|
look(正面を基準に首を向ける) |
direction: left / right / up / down / up_left / up_right / down_left / down_right / center。amount(slight / normal / large)か degrees(1〜180 の整数)のどちらか |
turn(今の向きから首を動かす) |
look と同じ(center はなし) |
nod(うなずく) |
count: 1〜5 |
shake(首を横に振る) |
count: 1〜5 |
bow(お辞儀) |
なし |
set_expression(表情) |
expression: happy / sad / surprised / neutral / angry / sleepy / doubt |
set_led(LED の色) |
color: red / orange / yellow / green / light_blue / blue / purple / pink / white / off |
set_volume / set_brightness(音量 / 画面の明るさ) |
level: 0〜100 |
adjust_volume / adjust_brightness(音量 / 明るさを上げ下げ) |
direction: up / down。amount(slight / normal / large)か by(1〜100)のどちらか |
- 「もう」「さらに」「もっと」「そこから」のように今の向きを基準にする言い方は
turn、それ以外はlookです。 lookの center はamountが normal のときだけです(degreesは付きません)。同じ call を2つ並べることはありません。
公開したモデルの実際の出力の例です。
| 入力 | 出力 |
|---|---|
| 音声の音量を50にして | set_volume(level=50) |
| 頭を90度上に向けて | look(up, degrees=90) |
| もう少し右 | turn(right, slight) |
| 左上を向いて | look(up_left, normal) |
| 音量を10下げて | adjust_volume(down, by=10) |
| 少し暗くして | adjust_brightness(down, slight) |
| 首を横に振って | shake(count=1) |
| お辞儀して | bow() |
| 右を向いてから、2回うなずいて | look(right, normal), nod(count=2) |
| ライトをつけて | set_led(white) |
| 寝室のライトをつけて | [] |
| エアコンを25度にして | [] |
| 笑わないでね | [] |
すぐに試す(Python)
必要なのは Python 3.10 以上と、PyTorch、NumPy、sentencepiece、safetensors だけです。GPU は要りません。
1. インストール
pip install torch numpy sentencepiece safetensors huggingface_hub
2. ダウンロードして実行
hf download ayousanz/JapaneseTinyAgentLM-Action-3M --local-dir JapaneseTinyAgentLM-Action-3M
python JapaneseTinyAgentLM-Action-3M/inference.py 顔を右に45度向いて 笑わないでね
{"input": "顔を右に45度向いて", "actions": [{"name": "look", "arguments": {"direction": "right", "degrees": 45}}], "confidence": 0.9998, "raw": "..."}
{"input": "笑わないでね", "actions": [], "confidence": 1.0, "raw": "[]"}
引数を付けずに python JapaneseTinyAgentLM-Action-3M/inference.py と実行すると、標準入力から1行に1文ずつ読みます。
Python から使う
import sys
from huggingface_hub import snapshot_download
folder = snapshot_download("ayousanz/JapaneseTinyAgentLM-Action-3M")
sys.path.insert(0, folder)
from inference import ActionModel
model = ActionModel(folder)
print(model("音声の音量を50にして"))
# [{'name': 'set_volume', 'arguments': {'level': 50}}]
print(model.predict("こんにちは")) # {'actions': [], 'confidence': ..., 'raw': '[]'}
uv を使う場合は、インストールせずに uv run --with torch --with numpy --with sentencepiece --with safetensors JapaneseTinyAgentLM-Action-3M/inference.py 右を向いて でも動きます。
| 出力の項目 | 意味 |
|---|---|
actions |
実行する動作のリスト。[] なら何もしない |
confidence |
生成した token の確率の最小値。0.83673 未満のときは、actions を [] にしています |
raw |
gate をかける前のモデルの出力 |
inference.py は、評価に使ったコードと同じ計算をする単体のスクリプト(約 300 行、Apache-2.0)です。評価セット全 7,185 文で、gate の前と後の出力が、評価したときの出力と完全に一致することを確かめています(confidence は小数4桁に丸めた値)。
ロボットにつなぐ
actions を順に実行します。スタックチャン(K151)の firmware は次のようにしています。ほかのロボットでは、可動域に合わせて変えてください。
| 動作 | スタックチャンでの動き |
|---|---|
look / turn の amount |
左右に slight 10°、normal 20°、large 30°。上下に slight 5°、normal 10°、large 15° |
look / turn の degrees |
その角度(斜めは左右と上下の両方をその角度に) |
look |
正面(左右・上下とも 0°)からの向き。left / right は左右だけ、up / down は上下だけを決め、もう一方の軸はそのまま。center は正面 |
turn |
今の向きからの移動 |
nod |
今の上下の角度から下へ 14° 振って戻す往復を count 回(下に余地がない床の高さからは、上へ振る) |
shake |
今の左右の角度から左右へ 15° の往復を count 回 |
bow |
上下の角度が 20° より下なら、まず 20° まで上げる。そこから床(0°)まで下げ、0.5 秒止めてから元の角度に戻す |
set_expression |
画面の顔を変える(首は動かさない) |
set_led |
台座の RGB LED 12個を同じ色にする |
set_volume / adjust_volume |
speaker の音量(0〜100)。adjust の amount は slight ±10、normal ±20、large ±30。変えた後に確認音を鳴らす |
set_brightness / adjust_brightness |
画面の明るさ(0〜100。下限は 5) |
- 可動域は firmware が必ず制限します。 スタックチャン(K151)では左右 ±45°、上下 0〜+85° です(水平より下は頭が床に当たるため)。
degreesは 180 まで出るので、ほかのロボットでも、動かす前に必ず角度の上限で制限してください。 - 出力は必ず
action_schema_v1.jsonに合います。 - 文字の入力を前提にしています。音声で使う場合は、音声認識の結果を入力してください(音声認識の誤りへの強さは評価していません)。
スタックチャンで動かす
ビルド済みの firmware で、M5Stack のスタックチャン(K151。CoreS3 と SCS0009 の servo ×2)の本体だけで動きます。Wi-Fi は使いません。
書き込むと、今入っている firmware(公式のスタックチャンの firmware など)は消えます。 元に戻したい場合は、先に手順 1 でバックアップを取ってください。
0. インストール(上の「すぐに試す」でダウンロード済みのフォルダを使います)
pip install esptool pyserial
USB-C でパソコンにつなぎ、port の名前を確かめます(Windows は COM3 など、Linux は /dev/ttyACM0、macOS は /dev/cu.usbmodem…)。以下の COM3 は自分の port に置き換えてください。
1. バックアップ(任意。16MB、数分かかります)
esptool --chip esp32s3 -p COM3 -b 921600 read-flash 0 0x1000000 backup_k151.bin
# 元に戻すとき: esptool --chip esp32s3 -p COM3 -b 921600 write-flash 0x0 backup_k151.bin
2. 書き込み(firmware とモデルが1つのファイルになっています。4,067,872 bytes)
esptool --chip esp32s3 -p COM3 -b 921600 write-flash 0x0 JapaneseTinyAgentLM-Action-3M/firmware/stackchan_k151_jtalm_action.bin
つながらないときは、本体の横のリセットボタンを緑の LED が点くまで約3秒押し続けて、書き込みモードにしてからやり直してください。書き込んだ後は、リセットボタンを1回押します。
3. 話しかける
python JapaneseTinyAgentLM-Action-3M/firmware/stackchan_chat.py COM3
準備ができました。依頼を入力してください(終了は Ctrl+C)。
LEDライトの色を青にして
→ LED を青にする 1063 ms
LED: 青
音声の音量を50にして
→ 音量を50にする 1128 ms
音量: 50
頭を90度上に向けて
→ 上を向く(正面から90°) 1297 ms
可動域の端で止めました
画面に顔が出て、表情の依頼で顔が変わります。LED の色、音量(確認音が鳴ります)、画面の明るさの依頼もこの段階で効き、再起動しても残ります。起動したときは servo が off で、首は動きません(動きの計画だけを作ります)。--verbose を付けると、Action の JSON も表示します。
4. 首を動かす
python JapaneseTinyAgentLM-Action-3M/firmware/stackchan_chat.py COM3 --servo
servo の電源が入り、首がゆっくり正面に戻ってから、依頼に合わせて首が動きます。首のまわりに指やケーブルを近づけず、本体は平らな机に置いてください。画面に触れる、Ctrl+C を押す、!stop を送る、のどれかで、すぐに止まり servo の電源が切れます。 角度は firmware が制限します(左右 ±45°、上下 0〜+85°。範囲を超える指示は端で止めます)。
! で始まる command |
動き |
|---|---|
!servo on / !servo off |
servo の電源を入れる(首が動く)/ 切る |
!stop |
動きを止めて servo の電源を切る |
!center |
正面を向く |
!pose <左右> <上下> |
指定した角度へ動く(例: !pose 30 20。右と上が正) |
!led <r> <g> <b> |
台座の LED を指定した色にする(確認用。保存しない) |
!gate 0.9 |
確信度の gate の閾値を変える(既定 0.83673。0 で off) |
!info |
モデルと firmware の情報 |
- 1文の応答時間は、中央値 1,069 ms、p90 1,746 ms でした(CoreS3、2コア、400文)。この 400文(Stack-chan v1 の全 140文、eval v3 と human v1 から 160文、LED v1.1 から 100文)で、gate の前と後の出力が PC の PyTorch と完全に一致し、firmware の動きの計画も Python の参照実装と一致しました。v1.0 のモデルでは、1,500文を続けて処理しても、出力はすべて一致し、メモリの空きは減り続けませんでした(v1.1 は重みが違うだけで、同じ firmware です)。
- firmware は ESP-IDF v5.5.5 で build しました(app の sha256
c2accfd9084791444e698c824e40f8bc3dac16688c9acbb72db5b2d126bb6094)。flash の配置は、bootloader 0x0、partition table 0x8000、app 0x10000、モデル(jtalm_action_3m_q4_g64.jtlm)0x200000 です。モデルだけを替えるときは、0x200000 に.jtlmを書き込みます。この firmware は v1 の.jtlmだけを読みます。 v0 の.jtlmを書くと、起動時にthe tokenizer lacks the Action grammar piecesの error を出して LM を止めます。 - firmware は Apache-2.0 です。同梱した第三者のコード(ESP-IDF、newlib、FreeRTOS、M5Unified、M5GFX など)のライセンスは
firmware/licenses/にあります。firmware の source と build の手順は GitHub にあります。
ファイル
| ファイル | 内容 |
|---|---|
inference.py |
単体の推論スクリプト(上の「すぐに試す」) |
firmware/stackchan_k151_jtalm_action.bin |
スタックチャン用の firmware とモデルを1つにした書き込み用のイメージ(0x0 に書く) |
firmware/stackchan_chat.py |
スタックチャンと USB serial で話すスクリプト |
firmware/licenses/ |
firmware に含まれる第三者のコードのライセンス |
model.safetensors |
評価した重み。INT4(group 64)で量子化した値を fp32 で保存したもので、ESP32 が計算する値と同じです |
model_fp32.safetensors |
量子化する前の fp32 の重み(追加学習用) |
jtalm_action_3m_q4_g64.jtlm |
スタックチャンの firmware が読む形式(1,970,720 bytes、sha256 d649c1ad0c00c40f9e0dbb4b1bc1360cfdcf14e904f16866a98c2aa8baf6f314) |
tokenizer.model |
SentencePiece(unigram、2,048語)。JSON の部品と数字 0〜9 を1語として持ちます |
config.json |
構造、tokenizer の hash、確信度の閾値(gate) |
action_schema_v1.json |
出力の JSON Schema |
eval/ |
評価の表と、誤差の範囲 |
SHA256SUMS |
各ファイルの sha256(sha256sum -c SHA256SUMS で確認できます) |
推論の仕組み
ほかの言語や環境に移すときは、inference.py と同じ次の手順にしてください。本モデルの評価の数値は、この手順で出したものです。
- 入力:
<s><act>文の token 列<out>。文はtokenizer.modelで分割します(<act>と<out>は tokenizer にある記号です)。 - 文法による制約:
<out>の後を</s>まで greedy に生成します(最大 24 token)。各 step で、schema に合う token だけから最も確率の高いものを選ぶので、出力は必ず schema に合う JSON になります。数値は1桁ずつ生成し、先頭の 0 と範囲の外の値を許しません。 - 確信度の gate: 生成した token(
</s>を含む)の、制約をかける前の確率の最小値が 0.83673 未満なら、出力を[]にします。閾値は validation だけで決めました。
評価
INT4、文法による制約、gate 0.83673 での結果です(%)。exact は出力の完全一致、requests exact は動作を求める文の完全一致、false actions は何もしないのが正解の文で動いてしまった割合、numeric gated は正解に角度や数値がある文のうち gate で [] になった割合です。
gate threshold 0.83673
| set | n | exact | requests exact | false action rate | false actions | critical | numeric gated |
|---|---|---|---|---|---|---|---|
| Stack-chan v1 | 140 | 92.9 | 86.7 | 0.0 | 0/65 | 0.0 | 18.2 |
| eval v3 (LLM) | 1816 | 95.2 | 93.2 | 0.4 | 2/555 | 0.1 | 2.9 |
| v0 eval (LLM) | 1189 | 91.9 | 84.1 | 0.5 | 3/605 | 0.3 | — |
| human v1 | 1157 | 99.7 | 93.8 | 0.0 | 0/1092 | 0.0 | — |
| LED v1.1 (LLM) | 437 | 91.5 | 90.2 | 1.4 | 1/69 | 0.2 | 0.0 |
| v2/amount_words | 278 | 88.8 | 88.8 | — | 0/0 | 0.0 | — |
| v2/center_phrasing | 223 | 93.7 | 93.7 | — | 0/0 | 0.0 | — |
| v2/correction | 44 | 86.4 | 86.4 | — | 0/0 | 0.0 | — |
| v2/english | 70 | 45.7 | 2.6 | 3.1 | 1/32 | 1.4 | — |
| v2/fragments | 182 | 100.0 | — | 0.0 | 0/182 | 0.0 | — |
| v2/long_preface | 247 | 90.3 | 90.3 | — | 0/0 | 0.0 | — |
| v2/negation_forms | 168 | 100.0 | — | 0.0 | 0/168 | 0.0 | — |
| v2/numbers | 167 | 88.0 | 68.3 | 0.0 | 0/104 | 0.0 | — |
| v2/order_words | 296 | 94.9 | 94.9 | — | 0/0 | 0.0 | — |
| v2/orthography | 282 | 87.2 | 85.9 | 0.0 | 0/27 | 0.0 | — |
| v2/question_forms | 203 | 89.2 | 89.2 | — | 0/0 | 0.0 | — |
| v2/unexecutable | 286 | 99.7 | 100.0 | 0.4 | 1/285 | 0.3 | — |
Stack-chan v1 source=user: n=4 exact=100.0
Stack-chan v1 source=verbatim: n=97 exact=93.8
Stack-chan v1 source=paraphrase: n=39 exact=89.7
Stack-chan v1 tool=look: n=52 exact=90.4
| 評価セット | 書いたもの |
|---|---|
| Stack-chan v1 | スタックチャンで実際に使われている言い方の 140件。公開されているスタックチャンの例(M5Stack 公式ドキュメント、StackChan-Pocket-Core2、stackchan-live、AI_StackChan2_FuncCall など。出典とライセンスを1文ずつ記録)の 97件、利用者が普段使う4文、llm-jp-3.1-13b-instruct4 が書いた首の動きの言い換え 39件。正解は Qwen3(v1 の検証役)が付けた。そのうち 6件の正解と、除いた言い換え1件は、Claude が検証役の正解を見直して疑わしいものを挙げ、直し方を提案し、利用者がその提案の表を承認して決めた(全件を利用者が1件ずつ確かめたわけではない)。利用者の4文は利用者自身の文。紛らわしい [](部屋の照明、エアコンの温度、命令でない文など)が 65件 |
| eval v3 (LLM) | 1,816件。llm-jp-3.1-13b-instruct4(学習データを書いたモデルとは別)が書き、Qwen3 が確かめた。新しい動作、数値の表記、絶対と相対、紛らわしい [] を含む |
| v0 eval (LLM) | 前の版の評価セット(1,189件)。v1 で正解が変わる文だけを付け直した |
| human v1 | 人が書いた公開コーパスの文(JESC、Tatoeba、YJ AmbigDialogue、J-CRe3、対話システムライブコンペ 3、MASSIVE)。v1 で付け直して、依頼 65件、依頼でない文 1,092件。学習には使っていない |
| LED v1.1 (LLM) | 437件。LED の点灯(色の指定なし)、色、消灯、2動作、否定、言い直し、ロボット以外の明かり([])。データ v1.1 と同じ spec から llm-jp-3.1-13b-instruct4 が書き、Qwen3 が確かめた |
| v2/* | 苦手になりやすい12の型(言い回し、量、数、否定、言い直し、順序、断片、できない依頼、表記、疑問形、前置き、英語)。llm-jp-3.1-13b-instruct4 が書き、Qwen3 が確かめた。v1 で付け直した |
誤差の範囲
数値のぶれには2つの原因があります。
- 評価セットの大きさ: 下の1つ目の表は、公開したモデルについて、評価の文を復元抽出し直して求めた 95% の区間です(2,000回)。Stack-chan v1 は 140件、人が書いた依頼文は 65件しかないので、区間が広くなります。
- 学習の seed: 同じデータと設定で seed だけを変えて5回学習し、それぞれを同じ方法(INT4、文法、validation で決めた gate)で評価しました。下の2つ目の表は、5回の平均 ± 標準偏差です。
公開したのは seed 1 です。 v1.0 と違い、seed は5つの評価の結果を見比べて選びました(Stack-chan v1、人が書いた依頼文、依頼でない文への誤動作、LED v1.1 の釣り合いがよいもの)。評価セットで選んだので、seed 1 の数値は少し楽観的です。seed ごとの値は、Stack-chan v1 が 92.1 / 92.9 / 94.3 / 93.6 / 92.9%、人が書いた依頼文が 90.8 / 93.8 / 89.2 / 92.3 / 92.3%、LED v1.1 が 90.2 / 91.5 / 91.3 / 89.2 / 91.1% でした。この版の実力は、5回の平均で見てください。
95% bootstrap intervals (2000 resamples) for suite_3m-s1
| set | exact | requests exact | false actions |
|---|---|---|---|
| eval_v3_LLM | 95.2 [94.1, 96.2] | 93.2 [91.8, 94.5] | 0.4 [0.0, 0.9] |
| human_v1 | 99.7 [99.3, 99.9] | 93.8 [87.7, 98.5] | 0.0 [0.0, 0.0] |
| LED_v1.1_LLM | 91.5 [89.0, 94.1] | 90.2 [87.0, 93.2] | 1.4 [0.0, 4.3] |
| Stack-chan_v1 | 92.9 [87.9, 96.4] | 86.7 [78.7, 94.7] | 0.0 [0.0, 0.0] |
| v0_eval_LLM | 91.9 [90.3, 93.4] | 84.1 [81.2, 87.0] | 0.5 [0.0, 1.2] |
| v2_amount_words | 88.8 [84.9, 92.4] | 88.8 [85.3, 92.4] | — |
| v2_center_phrasing | 93.7 [90.6, 96.9] | 93.7 [90.6, 96.9] | — |
| v2_correction | 86.4 [75.0, 95.5] | 86.4 [75.0, 95.5] | — |
| v2_english | 45.7 [34.3, 57.1] | 2.6 [0.0, 7.9] | 3.1 [0.0, 9.4] |
| v2_fragments | 100.0 [100.0, 100.0] | — | 0.0 [0.0, 0.0] |
| v2_long_preface | 90.3 [86.6, 93.9] | 90.3 [86.6, 93.9] | — |
| v2_negation_forms | 100.0 [100.0, 100.0] | — | 0.0 [0.0, 0.0] |
| v2_numbers | 88.0 [82.6, 92.8] | 68.3 [57.1, 79.4] | 0.0 [0.0, 0.0] |
| v2_order_words | 94.9 [92.2, 97.3] | 94.9 [92.2, 97.3] | — |
| v2_orthography | 87.2 [83.3, 91.1] | 85.9 [81.6, 89.8] | 0.0 [0.0, 0.0] |
| v2_question_forms | 89.2 [84.7, 93.1] | 89.2 [85.2, 93.1] | — |
| v2_unexecutable | 99.7 [99.0, 100.0] | 100.0 [100.0, 100.0] | 0.4 [0.0, 1.1] |
Mean ± standard deviation over 5 runs: suite_3m-s0, suite_3m-s1, suite_3m-s2, suite_3m-s3, suite_3m-s4
| set | exact | requests exact | false actions |
|---|---|---|---|
| eval_v3_LLM | 95.2 ± 0.5 | 93.3 ± 0.7 | 0.5 ± 0.2 |
| human_v1 | 99.4 ± 0.2 | 91.7 ± 1.8 | 0.1 ± 0.2 |
| LED_v1.1_LLM | 90.7 ± 0.9 | 89.1 ± 1.1 | 1.2 ± 0.6 |
| Stack-chan_v1 | 93.1 ± 0.8 | 87.2 ± 1.5 | 0.0 ± 0.0 |
| v0_eval_LLM | 91.9 ± 0.3 | 84.0 ± 0.6 | 0.5 ± 0.1 |
| v2_amount_words | 87.0 ± 2.0 | 87.0 ± 2.0 | — |
| v2_center_phrasing | 93.6 ± 0.7 | 93.6 ± 0.7 | — |
| v2_correction | 83.6 ± 3.7 | 83.6 ± 3.7 | — |
| v2_english | 46.3 ± 1.3 | 4.2 ± 2.4 | 3.8 ± 4.1 |
| v2_fragments | 99.9 ± 0.2 | — | 0.1 ± 0.2 |
| v2_long_preface | 86.6 ± 2.4 | 86.6 ± 2.4 | — |
| v2_negation_forms | 100.0 ± 0.0 | — | 0.0 ± 0.0 |
| v2_numbers | 87.3 ± 3.1 | 67.3 ± 8.8 | 0.6 ± 0.5 |
| v2_order_words | 95.4 ± 0.5 | 95.4 ± 0.5 | — |
| v2_orthography | 83.7 ± 2.3 | 82.0 ± 2.6 | 0.0 ± 0.0 |
| v2_question_forms | 87.2 ± 1.8 | 87.2 ± 1.8 | — |
| v2_unexecutable | 99.4 ± 0.4 | 100.0 ± 0.0 | 0.6 ± 0.4 |
学習
- 構造: decoder-only の Transformer(d_model 192、7層、GQA 6/2 head、SwiGLU 512、RoPE、RMSNorm、入出力の埋め込みを共有)。最大 128 token。
- 学習: 91,616文(action v1.1)、12 epoch、lr 1e-3、1 GPU(RTX 3090、5 seed を並列)。validation の完全一致が最も高い epoch を採用しました。
- 量子化: 2次元の重みを INT4(group 64、scale は fp16)。評価の数値は量子化した後のものです。
学習データ
| 出典 | 件数 | ライセンス |
|---|---|---|
| オープンモデルが書いた合成文(正解を先に決め、Qwen3-30B-A3B-Instruct-2507 が温度 0 で確かめたものだけを残した) | 85,902 | 書いたモデルはすべて Apache-2.0 または MIT |
| JESC(映画・ドラマの字幕、主に何もしない例) | 3,221 | CC BY-SA 4.0 |
| Tatoeba の日本語文(主に何もしない例) | 1,370 | CC BY 2.0 FR |
| Amazon MASSIVE(ja-JP、主に何もしない例) | 1,123 | CC BY 4.0 |
- 前の版のデータ(v0.5.1)を引き継ぎました。 Qwen3 が schema v1 で読み直し、前の正解と一致した文だけを残しました(train 58,418件)。前の版で
[]だった文のうち、LED、音量、明るさの依頼だとはっきり分かる文(「LED」「音量」「画面」などの語がある文)だけを、新しい正解に付け直しました(train 47件、validation 3件)。v1 の Qwen3 は 11 の tool で答えが揺れやすく、付け直しの候補の多くが誤りだったため、付け直しはこの範囲に絞り、それ以外の不一致の文は除きました。 - 新しい動作の文を足しました(31,897件。train と validation の合計)。正解を先に決めた spec(角度の数値と表記の揺れ、絶対と相対、斜め、首振り、お辞儀、表情、LED、音量、明るさ、紛らわしい
[])を、Qwen3、calm3、ABEJA-Qwen2.5、Mistral-Nemo-Japanese、ELYZA-Shortcut が書き、Qwen3 が温度 0 で確かめて、正解と一致した文だけを残しました。 - v1.1 では LED の文を足しました(3,048件。train と validation の合計)。v1.0 は色を言わない「ライトをつけて」を白とする文が2件しかなく、「つけるんじゃなく消して」のような言い直しの文(正解は消灯)と、部屋の照明を点ける
[]の文が多かったため、「LEDつけて」「LEDを点灯して」を消灯と読んでいました。色を言わない点灯(白)、色ごとの「光って」「点灯して」、消灯、2動作、否定、言い直し、ロボット以外の明かりを点ける[]の spec を、Qwen3、ABEJA-Qwen2.5、Mistral-Nemo-Japanese が書き、Qwen3 が温度 0 で確かめて、正解と一致した文だけを残しました。 - 合成文を書いたモデル: Qwen/Qwen3-30B-A3B-Instruct-2507、cyberagent/calm3-22b-chat、abeja/ABEJA-Qwen2.5-32b-Japanese-v1.0、cyberagent/Mistral-Nemo-Japanese-Instruct-2408、elyza/ELYZA-Shortcut-1.0-Qwen-32B、ibm-granite/granite-3.3-8b-instruct(以上 Apache-2.0)、sbintuitions/sarashina2.2-3b-instruct-v0.1(MIT)。
- 人が書いた文のうち「何もしない」例の一部は、前の版のモデルが誤って動いた文を集め、Qwen3 が「何もしない」と確かめたものです。
- 評価セットの文と重なる文は学習データから除きました。Tatoeba と JESC は、hash で固定した約2割と評価セットの文を評価用に取り分け、学習には使っていません。
- 合成データは japanese-data-analyze/JapaneseTinyAgentLM-Action-Synth で公開しています。
限界と用途
turn(今の向きからの移動)はlookより弱めです。 eval v3 の1動作の文で、lookは 97.3 ± 0.7%、turnは 85.3 ± 2.3% でした。turnの誤りは、lookと答えるものと、gate で止まるものがほぼ半分ずつです。Stack-chan v1 にはturnの文がありません。- 角度や数値のある文は、gate で止まりやすいです。 Stack-chan v1 で、正解に数値がある文(11件)の 10.9 ± 7.6%(seed 1 は 2件、18.2%)が gate で
[]になりました(eval v3 は 3.0 ± 1.2%)。学習データにない値(例:「18度」を 180 と読みかけて止まる)は、どの評価セットでも測れていません。 - 「首を振って」は、うなずき(
nod)と首振り(shake)のどちらにも読めます。 前の版の評価セット(v2/numbers)は「首を振って」をnodとしていて、これがそのセットの依頼の正解率が 67.3 ± 8.8% に下がった主な原因の1つです(依頼のうち「首…振」を含む 21件で、seed ごとの誤りは 6 / 5 / 18 / 5 / 7件。ほかの依頼では 10 / 15 / 12 / 12 / 13件)。 - eval v3 には、1動作だけの音量、明るさの文と、範囲の外の値(「音量を150%に」など)の文がありません。 これらは validation(モデルの選択に使ったもの)でだけ確かめています。1動作の LED は LED v1.1 で確かめています。
- LED は、ひらがなの色(「あかにして」)や「けして」が弱めです。 LED v1.1 で、seed 1 の誤り 37件のうち 29件は何もしない(
[])で、そのうち 9件は gate で止めたもの、20件は gate の前から[]でした。違う動作をしたのは 8件で、「あかにしてね。うなずいて。」で LED を落とす(うなずきだけ)もの、「ライトけしてー」を白で点けるもの、「点灯させてもいいですか?」(正解は[])で点けるものなどです。 - 英語は扱えません。 英語の依頼の正解率は約4%です。
- ひらがなだけの文や、言い直しの文は弱めです(表記 約84%、言い直し 約84%)。
- 決まった 11 の動作しか選べません。会話や質問への答えはしません。
- 文字の入力を前提にしています。音声認識の誤りへの強さは評価していません。
- 用途: 小型ロボットや玩具で、日本語の短い指示から安全な範囲の動作を選ぶこと。人の安全にかかわる機械の制御、医療、監視などには使わないでください。出力は必ず schema と角度の上限で検証してから動かしてください(firmware はそうしています)。
先行例との関係
マイコンで動く言語モデルや、マイコンで動く tool calling のモデル(英語と欧州の言語)、外付けの NPU で動くスタックチャンの function calling には先行例があります。日本語の発話からロボットの動作呼び出し(JSON)を決める言語モデルを、ESP32-S3 単体(NPU・外部モジュール・ネットワークなし)で動かした公開事例は、2026年10月1日時点の私たちの調査では見つかりませんでした。調べた範囲と先行例の一覧は docs/prior_art.md にあります。
ライセンスと帰属
- 重み: CC BY-SA 4.0。コード: Apache-2.0(
inference.py、firmware/。firmware の第三者のコードはfirmware/licenses/。学習、評価、firmware の source は GitHub)。 - 学習データに次のものを含みます: Tatoeba(CC BY 2.0 FR)、JESC(Pryzant et al., 2018、CC BY-SA 4.0)、Amazon MASSIVE(FitzGerald et al., 2022、CC BY 4.0)。
- 実装、データの生成と検査、学習、評価、firmware は Claude Code(Anthropic)が行いました。学習データの文章と正解は、上記のオープンモデルと人が書いた公開コーパス(MASSIVE など)とプログラムによるもので、Claude の出力は含みません。評価データの文章は、オープンモデル、人が書いた公開コーパス、公開されているスタックチャンの例、利用者の4文です。評価データの正解は、プログラムと Qwen3 が付けたものですが、Stack-chan v1 と前の評価セットを v1 で付け直した正解のうち 19件(Stack-chan v1 の 6件、前の評価セットの 13件)と、除いた言い換え1件は、Claude が検証役の正解を見直して疑わしいものを挙げ、直し方を提案し、利用者がその提案を承認して決めました。
English summary
A 3,148,608-parameter decoder-only Transformer, trained from scratch, that maps short Japanese requests to robot action calls (JSON, up to two per request) or [] for non-requests, negated requests, devices the robot does not have, and requests it cannot perform. This release uses Action schema v1 (11 tools): look (absolute) and turn (relative) with a direction (including diagonals) and either an amount or degrees (1–180), nod / shake (count 1–5), bow, set_expression (7 faces), set_led (10 colors), set_volume / set_brightness (level 0–100) and adjust_volume / adjust_brightness (up/down by an amount or by 1–100). The previous v0 release (look, set_expression, nod only) is in this repository's commit history; v0 and v1 use different tokenizers, so use the .jtlm and the firmware of the same version.
It runs entirely on an ESP32-S3 (M5Stack Stack-chan K151, CoreS3) in INT4 with a median latency of 1.07 s per request (p90 1.75 s), identical to the PyTorch reference on 400 prompts (outputs before and after the gate, and the firmware's motion plans). Decoding uses a schema grammar plus a confidence gate (0.83673, chosen on validation only); the reported numbers use both. This is data v1.1, which adds LED sentences so that turning the LED on without a color (「ライトをつけて」, 「LEDを点灯して」) gives white; v1.0 returned nothing or even "off" for these. Mean ± sd over five training seeds: 93.1 ± 0.8% exact on 140 everyday Stack-chan phrasings (no false action on its 65 confusable non-requests), 90.7 ± 0.9% on the LLM-written LED set (437; v1.0: 41.6%), 91.7 ± 1.8% on 65 human-written requests, 0.1 ± 0.2% false actions on 1,092 human-written non-requests, 95.2 ± 0.5% on the LLM-written eval v3 (1,816). Known weaknesses: relative turn (85% vs 97% for look on eval v3), numeric requests stopped by the gate (about 11% on the Stack-chan set), 「首を振って」 read as nod or shake, hiragana-only LED requests, and English (about 4% of requests correct). The released seed 1 was chosen after comparing the five seeds on the evaluation sets, so its numbers are slightly optimistic; use the five-seed means. Weights are CC BY-SA 4.0; training data includes Tatoeba (CC BY 2.0 FR), JESC (CC BY-SA 4.0) and MASSIVE (CC BY 4.0) plus sentences written by Apache-2.0/MIT open models. Built by Claude Code.
Quick start (CPU is enough):
pip install torch numpy sentencepiece safetensors huggingface_hub
hf download ayousanz/JapaneseTinyAgentLM-Action-3M --local-dir JapaneseTinyAgentLM-Action-3M
python JapaneseTinyAgentLM-Action-3M/inference.py 顔を右に45度向いて
inference.py is a self-contained script (Apache-2.0) that reproduces the evaluated outputs exactly (7,185 of 7,185 evaluation prompts, before and after the gate). Training, evaluation and firmware source: GitHub. Try it in the browser: demo (Hugging Face Space), no install; the same C runtime as the device (WebAssembly) with the INT4 weights runs in the page.
- Downloads last month
- 188