CoolFace
Modelpublic

hellohazime/qwen3-1p7b-pokellm-lora_50k_ev0p05

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes25downloads
Model Card

Qwen3-1.7B PokéLLM LoRA (Gen9 OU / JSON Action Selector)

Summary: Qwen/Qwen3-1.7B を LoRA で事後学習し、ポケモン Showdown の Gen9 OU 対戦における 単手意思決定(行動選択)を行う軽量アダプタです。 本モデルは、与えられた候補集合に対して 厳密 JSON で {"action":"index::<k>"} を返すことを目的に最適化されています。 (index::<k> は、あなたのエージェントが提示する候補リストの 0-based インデックス)


Model Details

  • —Base model: Qwen/Qwen3-1.7B
  • —Adapter type: LoRA (PEFT)
  • —Task: Pokémon Showdown Gen9 OU の 1 手意思決定(行動選択)
  • —I/O 仕様: 入力: 観測(軽量テキスト or 構造化を文字列化)+候補 CANDIDATES(内部で index にマッピング) 出力: 厳密 JSON 一個 { "action": "index::<k>" }
  • —Intended framework: 🤗 Transformers + PEFT(PyTorch)
  • —License: Base モデルに準拠(Qwen/Qwen3-1.7B のライセンスをご確認ください)
  • —Author : 波浪 創(hellohazime)

What this model is / isn’t

  • —✅ すること: 候補(技 / 交代など)から 1 つを選ぶ。
  • —⚠️ しないこと: 一般的な雑談・長文生成・マルチターン方策学習・ダメージ計算の厳密再現。

Uses

Direct Use

  • —対戦中の観測テキストと、候補キー(内部で index に変換したもの)を提示し、1 手を選択させる。
  • —出力は 必ず 1 行 1 JSON。解析側は action を読み取り、あなたの index_map[k] に解決して実行してください。

Downstream Use

  • —poke-env / Pokémon Showdown クライアントと組み合わせれば、ローカル対戦エージェントとして利用できます。
  • —学習済みプロンプト・スキーマに依存します。異なるスキーマで使う場合は再学習を推奨。

Out-of-Scope

  • —一般領域の対話、長文化・推論タスク、Gen9 OU 以外のフォーマットへの強い汎化は想定していません。

How to Get Started

Load with PEFT (Transformers)

python
from transformers import AutoTokenizer, AutoModelForCausalLM
from peft import PeftModel

BASE = "Qwen/Qwen3-1.7B"
ADAPTER = "hellohazime/qwen3-1p7b-pokellm-lora_50k_ep0p05"  

tok = AutoTokenizer.from_pretrained(BASE, trust_remote_code=True)
if tok.pad_token_id is None and tok.eos_token_id is not None:
    tok.pad_token = tok.eos_token

base = AutoModelForCausalLM.from_pretrained(BASE, trust_remote_code=True, device_map="auto")
model = PeftModel.from_pretrained(base, ADAPTER)

# --- 推論の例(厳密JSONを狙うプロンプト) ---
obs = "turn | 3\nyour_active | Gholdengo\nopp_active | Great Tusk\nmoves | Make It Rain, Shadow Ball, Trick, Focus Blast"
# 例: allowed は内部で index に並べ替えた候補(move群→switch群)に対応
allowed = ["index::0","index::1","index::2","index::3"]  # 例
prompt = (
    "You are a Gen9 OU single-battle agent.\n"
    "Return exactly one JSON object on a single line.\n"
    'Schema: {"action": "index::<k>"} No markdown, no extra text.\n'
    f"ALLOWED: {' | '.join(allowed)}\n\n"
    f"{obs}\n\n"
    "Action:"
)

inputs = tok(prompt, return_tensors="pt").to(model.device)
out_ids = model.generate(
    **inputs,
    max_new_tokens=48,
    do_sample=False,  # 温度0相当
    eos_token_id=tok.eos_token_id,
    pad_token_id=tok.eos_token_id
)
print(tok.decode(out_ids[0], skip_special_tokens=True))
Note: MLX ランタイムで LoRA を直接ロードするには別途変換が必要です(標準の PEFT/Torch では上記のように動作します)。

Training Details

Training Data

  • —出典: jakegrigsby/metamon-parsed-replays(Showdown リプレイの構造化アーカイブ)
  • —フィルタ: Gen9 OU / Elo ≥ 1500 を中心に抽出・整形
  • —生成された SFT データは以下のindex スキーマ(簡略):
  • —system: 「厳密 JSON で 1 手のみ返す」等の指示
  • —user: { "state": {...}, "CANDIDATES": ["index::0", ...] }
  • —assistant: { "action": "index::<k>" }

Preprocessing

  • —候補(move / switch)を アルファベット順に整列し、index::<k> に対応付け。
  • —観測は軽量テキスト(ターン/自他アクティブ/使用可能技の見出し名 etc.)に要約。
  • —長さ上限(cutoff): 1024 tokens 目安。

Training Procedure (LoRA / SFT)

  • —PEFT LoRA: r=8, alpha=16, dropout=0.05, bias="none" target\_modules: q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj
  • —Optimizer: AdamW(transformers.TrainingArguments(optim="adamw_torch"))
  • —LR: 2e-4 近辺(スモーク→本学習でスケール)
  • —Batch size: 端末依存(例: per_device_train_batch_size=8, gradient_accumulation_steps=1)
  • —Max steps: 12500
  • —Evaluation: eval_ratio ≈ 5%, eval_steps=500 前後 EarlyStoppingCallback(patience=3, metric=eval_loss)
  • —Precision: fp32(Mac/MPS で安定運用)
実行スクリプトは TRL SFTTrainer を用いた標準的な SFT(packing 無効、formatting_func で chat template を適用)構成です。

Evaluation

Protocol

  • —環境: ローカル Pokémon Showdown (:8080), poke-env 経由
  • —形式: gen9ou(同一チーム同士で LLM vs Random の簡易ベースライン)
  • —強制スキーマ: 厳密 JSON 一個({"action": "index::<k>"})

Result

normal

Baseline vs Random (Gen9 Random Battle, N=10)

ModelAdapterWin%Fallback%Avg Lat(ms)
Qwen/Qwen3-1.7B—50.031.74450.3
datasize 50k
uv run python eval_vs_ou.py \
  --n_battles 10 \ 
  --backend hf \
  --model Qwen/Qwen3-1.7B \
  --adapter outputs/qwen3-1p7b_lora_50k_ev0p05 \
  --format gen9ou \
  --schema index \
  --team1 teams/ou_team.txt \
  --team2 teams/ou_team.txt
ModelWin%Fallback%Avg Lat(ms)p95(ms)Decis.Battles
Qwen/Qwen3-1.7B + outputs/qwen3-1p7blora50k_ev0p0570.000.001646.11731.636310
  • —補足: 対戦相手は poke-env の RandomPlayer。本 LoRA の “index スキーマ厳守” と最小限観測だけで、安定した JSON 出力を確認。
  • —さらなる妥当性評価(他フォーマット、強い相手、別チーム、長期戦)や人手検証は今後の課題です。

Bias, Risks, and Limitations

  • —単手方策であり、長期的なプランニングやリソース管理は学習していません。
  • —index スキーマ依存のため、プロンプト逸脱や候補整列順の不一致で性能が大きく劣化します。
  • —データは公開リプレイ由来で、プレイヤースキルやメタに偏りがあり得ます。
  • —ダメージ計算・乱数・特性相互作用は簡略観測のみで与えており、完全再現ではありません。

Recommendations

  • —生成の健全性チェック(JSON 解析、候補外出力のフォールバック)を必ず実装してください。
  • —実運用では 評価対戦の拡充(様々な構築・相手・ルール)を推奨します。

Technical Specifications

Architecture

  • —Qwen3-1.7B(Causal LM)+ LoRA(PEFT)

Software

  • —Transformers / TRL / PEFT / PyTorch(MPS)
  • —Tokenizer は base に付属の chat template を使用(無い場合は簡易フォールバック)

How to Cite / Credit

  • —Base: Qwen/Qwen3-1.7B
  • —Data inspiration: metamon-parsed-replays(Showdown 由来の公開リプレイ構造化)

Model Card Authors

  • —波浪 創(hellohazime) *

Framework versions

  • —PEFT 0.17.1(動作確認)
  • —Transformers / TRL は 2025 時点の安定版で確認(詳細は training_args.bin を参照)