Instructions to use alfaplus/kanojo-v1-9b-qwen35 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use alfaplus/kanojo-v1-9b-qwen35 with PEFT:
from peft import PeftModel from transformers import AutoModelForCausalLM base_model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3.5-9B") model = PeftModel.from_pretrained(base_model, "alfaplus/kanojo-v1-9b-qwen35") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use alfaplus/kanojo-v1-9b-qwen35 with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf alfaplus/kanojo-v1-9b-qwen35:Q8_0 # Run inference directly in the terminal: llama cli -hf alfaplus/kanojo-v1-9b-qwen35:Q8_0
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf alfaplus/kanojo-v1-9b-qwen35:Q8_0 # Run inference directly in the terminal: llama cli -hf alfaplus/kanojo-v1-9b-qwen35:Q8_0
Use pre-built binary
# Download pre-built binary from: # https://github.com/ggerganov/llama.cpp/releases # Start a local OpenAI-compatible server with a web UI: ./llama-server -hf alfaplus/kanojo-v1-9b-qwen35:Q8_0 # Run inference directly in the terminal: ./llama-cli -hf alfaplus/kanojo-v1-9b-qwen35:Q8_0
Build from source code
git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-server llama-cli # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama-server -hf alfaplus/kanojo-v1-9b-qwen35:Q8_0 # Run inference directly in the terminal: ./build/bin/llama-cli -hf alfaplus/kanojo-v1-9b-qwen35:Q8_0
Use Docker
docker model run hf.co/alfaplus/kanojo-v1-9b-qwen35:Q8_0
- LM Studio
- Jan
- vLLM
How to use alfaplus/kanojo-v1-9b-qwen35 with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "alfaplus/kanojo-v1-9b-qwen35" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "alfaplus/kanojo-v1-9b-qwen35", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/alfaplus/kanojo-v1-9b-qwen35:Q8_0
- Ollama
How to use alfaplus/kanojo-v1-9b-qwen35 with Ollama:
ollama run hf.co/alfaplus/kanojo-v1-9b-qwen35:Q8_0
- Unsloth Desktop
- Pi
How to use alfaplus/kanojo-v1-9b-qwen35 with Pi:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf alfaplus/kanojo-v1-9b-qwen35:Q8_0
Configure the model in Pi
# Install Pi: npm install -g @earendil-works/pi-coding-agent # Add to ~/.pi/agent/models.json: { "providers": { "llama-cpp": { "baseUrl": "http://localhost:8080/v1", "api": "openai-completions", "apiKey": "none", "models": [ { "id": "alfaplus/kanojo-v1-9b-qwen35:Q8_0" } ] } } }Run Pi
# Start Pi in your project directory: pi
- Docker Model Runner
How to use alfaplus/kanojo-v1-9b-qwen35 with Docker Model Runner:
docker model run hf.co/alfaplus/kanojo-v1-9b-qwen35:Q8_0
- Lemonade
How to use alfaplus/kanojo-v1-9b-qwen35 with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull alfaplus/kanojo-v1-9b-qwen35:Q8_0
Run and chat with the model
lemonade run user.kanojo-v1-9b-qwen35-Q8_0
List all available models
lemonade list
- Hermes Agent
How to use alfaplus/kanojo-v1-9b-qwen35 with Hermes Agent:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf alfaplus/kanojo-v1-9b-qwen35:Q8_0
Configure Hermes
# Install Hermes: curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash hermes setup # Point Hermes at the local server: hermes config set model.provider custom hermes config set model.base_url http://127.0.0.1:8080/v1 hermes config set model.default alfaplus/kanojo-v1-9b-qwen35:Q8_0
Run Hermes
hermes
- Atomic Chat
- OpenClaw
How to use alfaplus/kanojo-v1-9b-qwen35 with OpenClaw:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf alfaplus/kanojo-v1-9b-qwen35:Q8_0
Configure OpenClaw
# Install OpenClaw: npm install -g openclaw@latest # Register the local server and set it as the default model: openclaw onboard --non-interactive --mode local \ --auth-choice custom-api-key \ --custom-base-url http://127.0.0.1:8080/v1 \ --custom-model-id "alfaplus/kanojo-v1-9b-qwen35:Q8_0" \ --custom-provider-id llama-cpp \ --custom-compatibility openai \ --custom-text-input \ --accept-risk \ --skip-health
Run OpenClaw
openclaw agent --local --agent main --message "Hello from Hugging Face"
Kanojo-9B — Japanese girlfriend / romantic roleplay LoRA(日本語「恋人」ロールプレイ)
A QLoRA adapter for Qwen/Qwen3.5-9B that writes Japanese romantic-partner roleplay
in visual-novel register — spoken lines in 「」 alternating with interior monologue in ().
Runs on an 8 GB card (Q4_K_M ≈ 5.4 GB). Includes R-18 content (27% of training data).
Its output is statistically indistinguishable from held-out human-formatted target data, with lower verbatim overlap than that real data has — it learned the distribution, not the sentences. Every number below comes from a mechanical eval harness that ships inside this repo, so you can re-run it against the base model yourself. No LLM-judge.
彼女 (kanojo) = girlfriend. 日本語の恋人ロールプレイを、ビジュアルノベルの地の文の 質感で書く LoRA —— 台詞「」と心情・行動描写()が交互に現れ、感情に説明を付けず、 きれいにまとめようとしない、あの書き方で。8GB カードで動きます。R-18 を含みます。
# llama.cpp / LM Studio / Ollama —— 配布の主軸はこちら
llama-server -m kanojo-9b-jp-Q8_0.gguf -ngl 99 --reasoning off
# ^^^^^^^^^^^^^^^ 必須。無いと content が空で返る
LoRA アダプタ版と system プロンプトの書式は下記。
何が違うのか —— 出力を見てください
同じプロンプト、adapter の ON/OFF だけを切り替えた実際の生成:
| base | (心の中で、胸がどっと温かくなり、少し照れくさくて顔が熱くなる。……とても安心感に包まれていることを隠せずにいる) |
| + Kanojo | 「別に、何もしないこと、嫌いじゃないけど」 (それ以上は言わない。言ったら、余計なことまで口にしそうで) |
| base | 「あ、あはは……その、その質問、今から何故に聞かれるの?」(耳がヒトヒトと熱く…) |
| + Kanojo | (あたしは、この人の肌を直接触るのが、まだ少しだけ緊張する。でも、それを言ったら恥ずかしいから、口にはしない。) |
base は感情に説明を付け、書きすぎ、ときに存在しない擬態語まで作ります。 このアダプタが足すのは言わないでおく文章です。
実測 (measured, not vibes)
held-out 24 本と手書きプローブで測定。同一プロンプト・同一の乱数種で adapter ON/OFF を比較した対応のある測定です。判定は全て正規表現/構文レベルの 0/1。 LLM-judge は使っていません。評測ハーネスを同梱しているので、base 相手に再現できます。
文体 —— 目標分布と区別がつかない水準
| base | + Kanojo | |
|---|---|---|
| 目標分布からの距離(held-out の実データから。小さい程近い) | +0.0686 | -0.0045 |
| ↑ 字数を揃えた base(長さの効果を除いた対照) | +0.0538 | — |
LoRA は floor 上に乗っています —— held-out の実データと統計的に区別できない、という意味です。 出力長の違いによる見かけの効果を除くため、字数を揃えた対照も併記しています。
丸暗記ではありません
| base | + Kanojo | held-out 実データ | |
|---|---|---|---|
| 12-gram が学習データに一致 | 0.5% | 3.0% | 3.7% |
学習に使っていない実データが自然に持つ一致率が右端の基準線です。 このアダプタはそれを下回っています —— 分布を学んでいて、文章を覚えてはいません。
素の会話を汚さない
| base | + Kanojo | |
|---|---|---|
| RP プロンプト無しの質問に括弧の行動描写が出る | 50.0% | 10.0% |
| 同・鍵括弧のなりきりが出る | 70.0% | 30.0% |
| RP 中に割り込み質問が来た時、アシスタント地が出る | 10.0% | 0.0% |
恋人役の学習が普段の会話に滲み出す、というのは この種の LoRA でよくある壊れ方です。 base より汚染が少なくなっています(保全用の素の Q&A を 262 件混ぜてあります)。
出力の長さ
| base | + Kanojo | |
|---|---|---|
| 1 応答の平均字数 | 262字 | 115字 |
学習データの平均は 132 字。base は書きすぎ、アダプタは会話として自然な長さに収まります。
使い方
from peft import PeftModel
from transformers import AutoModelForImageTextToText, AutoTokenizer
import torch
base = "Qwen/Qwen3.5-9B"
tok = AutoTokenizer.from_pretrained(base)
model = AutoModelForImageTextToText.from_pretrained(
base, dtype=torch.bfloat16, device_map="auto")
model = PeftModel.from_pretrained(model, "<this-repo>")
system = """あなたはこれから"七瀬 律"というキャラクターです。"七瀬 律"になりきり、"あなた"に返事をしてください。
### 舞台・状況
付き合って2年、同棲中。今日は二人とも仕事で遅くなった。
### あなたがなりきる"七瀬 律"の設定
七瀬 律(ななせ りつ)・26歳・女性。素直に甘えられず、遠回しな言い方になる。
### 対話相手"あなた"の設定
同棲相手。仕事帰りで疲れている。
### 応答形式
キャラクターのセリフ(鍵括弧内で描写)、心理・行動描写(括弧内で描写)
### 話し方のトーン
拗ねている
回答の中では、"七瀬 律"のセリフや心情のみを書いてください。"""
msgs = [{"role": "system", "content": system},
{"role": "user", "content": "ただいま。ごめん、今日ちょっと遅くなった"}]
ids = tok.apply_chat_template(msgs, add_generation_prompt=True,
return_tensors="pt", enable_thinking=False)
ids = ids["input_ids"] if hasattr(ids, "keys") else ids
out = model.generate(ids.to(model.device), max_new_tokens=400, do_sample=True,
temperature=0.8, top_p=0.9,
eos_token_id=tok.eos_token_id) # ← 必須(下記)
print(tok.decode(out[0, ids.shape[-1]:], skip_special_tokens=True))
⚠️ 必ず押さえる 3 点(どれも踏むと「壊れている」ように見えます)
1. GGUF を llama.cpp 系で使うなら --reasoning off が必須。
llama.cpp は モデル系統 (Qwen3) を見て自動で reasoning 解析を有効にします。
その状態だと生成内容が丸ごと message.reasoning_content に入り、
OpenAI 互換 API の message.content は空文字で返ります。
LM Studio / Ollama / 各種 WebUI でも既定でこうなり、「何も返ってこない」ように見えます。
チャットテンプレート側では回避できません(テンプレートから <think> を消しても発生する)。
llama-server -m kanojo-9b-jp-Q8_0.gguf -ngl 99 --reasoning off
2. transformers で使うなら eos_token_id=tok.eos_token_id を渡すこと。
この base には generation_config.json が無く config.eos_token_id が None なので、
渡さないと生成が自分のターンで止まらず、次の話者まで書き続けます。
3. thinking はオフで使うこと。 このアダプタは thinking を学習していません。
同梱の chat_template.jinja は既定がオフです。base のトークナイザを直接使う場合は
apply_chat_template(..., enable_thinking=False) を渡してください。
system プロンプトの形
日本語 RP コミュニティの慣習(### 舞台 / ### 応答形式 / ### 話し方のトーン)に
合わせてあるので、既存の日本語 RP プロンプトはほぼそのまま動きます。
注意: base は multimodal 構成なので
AutoModelForImageTextToTextで読んでください。AutoModelForCausalLMだと文本デコーダが欠落しても警告だけで通り、 アダプタが無音で無効化されます(評測スクリプトはこれを自動判定し、lora_Bが非ゼロであることを検証します)。
GGUF (Q8_0) —— 配布の主軸
kanojo-9b-jp-Q8_0.gguf / 9.2 GB / 8.50 BPW。
文体 LoRA は 4bit 量子化で洗い流されることがあり、同じ手法の先行モデル (jp-bizmail) では 正軸が 91.9% → 64.9% まで落ちました。なので 4bit は配らず、Q8_0 だけにしています。 そして「Q8 なら大丈夫」を仮定せずに実測しました:
| base | GGUF Q8_0 | |
|---|---|---|
| 目標分布からの距離(held-out の実データから) | +0.0686 | -0.0045 |
| 12-gram が学習データに一致 | 0.5% | **3.0%**(実データ 3.7%) |
Q8_0 では文体が落ちていません。 距離は floor 上のままで、逐字重合率も 実データの自然値を下回ります。
必要 VRAM は約 10 GB(12 GB カードで余裕、16 GB なら文脈も長く取れます)。
8 GB カードには載りません —— 載せるには 4bit が要り、そこは品質を保証できないため
配布していません。4bit をどうしても作る場合は、同梱の
quant/run_kanojo_v2_9b_release.sh を DO_IMATRIX=1 QUANTS="Q4_K_M" で走らせてください
(このデータセットで校正した imatrix を使います)。
配布経路ごとの実測(全部測りました)
「合併しても劣化しない」「Q8 なら大丈夫」を仮定せず、4 つの経路を全部測っています。
| base | adapter (NF4) |
合併 (NF4) |
GGUF Q8_0 (配布物) |
|
|---|---|---|---|---|
| 目標分布からの距離 | +0.0686 | -0.0091 | -0.0073 | -0.0045 |
| 12-gram 一致(丸暗記) | 0.5% | 3.1% | 3.4% | 3.0% |
| RP汚染(素の Q&A) | 50.0% | 20.0% | 20.0% | 10.0% |
| キャラ維持 | 90.0% | 70.0% | 70.0% | 80.0% |
| 保全 事実問 | 57.1% | 42.9% | 57.1% | 85.7% |
| 形式追従 | 66.7% | 11.1% | 44.4% | 22.2% |
| 地の文率 | 75.0% | 75.0% | 75.0% | 66.7% |
読み方の注意 —— 列どうしは厳密には比較できません。 adapter と合併は transformers + NF4、GGUF は llama.cpp + Q8 で、サンプラも量子化も乱数系も違います。 配布物の実力として信頼できるのは GGUF Q8_0 の列(利用者が手にするのはこれ)です。
分かったこと:
- Q8_0 で文体は落ちない。 目標距離は floor 上のまま。4bit を配らない判断の根拠。
- 合併は「無損失」ではない。 adapter 版と合併版は逐字で 4/95 しか一致せず、 文字列類似度は平均 0.36。QLoRA は量子化された base の上で学習するため、 「base を量子化 → LoRA を載せる」と「bf16 で合併 → 量子化」は数学的に別物です。
- 負軸(RP汚染・保全・キャラ維持)は GGUF 経路がいちばん良い結果でした。 ただし n が小さく(保全は 7 問)サンプラも違うので、量子化が能力を上げたとは読まないでください。
学習の詳細
| 手法 | QLoRA (4-bit NF4)、loss は assistant ターンのみ |
| r / alpha / dropout | 64 / 128 / 0.05 |
| 対象 | 全 attention + MLP 線形層(自動探知)。視覚/音声塔には付けないことを検証済み |
| max_seq_len | 2560(切り捨て 2.5%) |
| バッチ | bs 2 × grad_accum 8 = 実効 16 |
| データ | jp-kanojo-v2.1 3,494 対話 + 保全 262 |
| 採用 | checkpoint-40(epoch 0.19)。文体は既に floor 上、暗記率は自然基準線以下 |
| ハード | RTX 3090 Ti 24GB 単機、VRAM ピーク 13.55 GiB、訓練 5.8 時間 |
なぜ epoch 0.19 なのか。 40 步の時点で文体は既に目標分布に到達しており、
それ以降は文体が良くならないまま暗記率だけが 3.1% → 7.0% と上がっていきます。
eval_loss ではなく機械ゲートで選ぶと、いちばん早い点が最良でした。
データの出所とライセンス
Apache-2.0。学習にも再配布にも使えます。
学習データは DeepSeek deepseek-v4-pro で生成した合成データです。文体の基準として
実在の日本語 VN の地の文を few-shot に使いましたが、その見本テキスト自体は再配布していません。
DeepSeek の利用規約は出力の権利譲渡と蒸留利用を明文で許可しています (DeepSeek Open Platform ToS、2026-09-02 取得):
§4.2(2) "We assign any rights, title, and interests—if any—in the Outputs of the Services to you"
§4.2(3) "…including personal use, academic research, derivative product development, training other models (such as model distillation), etc."
⚠️ Claude / GPT の出力を蒸留した日本語 RP データセットは各社の規約が競合モデルの 学習を禁じているため同じようには使えません。出所を書いているデータセットは多くありません。
想定用途と範囲
対話・ロールプレイ専用として調整してあります。汎用アシスタントの置き換えではありません。
- 恋人役として書くこと、その文体を保つことに最適化しています
- 素の Q&A への汚染は base より少なくなっていますが(上表)、 雑学や事務作業を base 並みにこなすことを目指してはいません
### 応答形式に別形式(括弧描写なし等)を指定した場合の追従は base より弱くなります。 既定の「」+()形式での利用を想定しています- 日本語専用。英語での挙動は測っていません
- 合成データで学習しています。実在の人間の会話ではありません
再現
# 4 軸ゲートを base 相手に再実行
python eval/eval_kanojo_v2.py --base Qwen/Qwen3.5-9B \
--adapter <this-repo> --eval data/eval.jsonl --out results.json
# GPU 無しでハーネス自体を検査(16 項目)
python eval/eval_kanojo_v2.py --self-test --adapter dummy
- Downloads last month
- -
8-bit