evex-ft-1
Qwen3-0.6B-Base に、ある Discord サーバーの過去ログ 10,089,887 トークンを
追加学習したもの。狙いは知識ではなく口調で、147人ぶんの書き方が重みに入っている。
ゼロから学習した兄弟モデルもある —
evex-1 /
evex-2 (5.87M / tokenizer もログから作った)。
あちらは純度が高い代わりに荒く、こちらは Qwen の日本語を引き継いで読める代わりに
Qwen の借り物の知識が混ざる。
⚠️ 表示名が重みに入っている
話者ラベルが実在の人の表示名そのものです (あかり: にょ: たこ:)。
つまりこのモデルは特定の人になりきって書けます。evex-1 / evex-2 は匿名トークン
(<|s0|>) なので、そこが決定的に違います。
- 出力をその人が書いたものとして扱ってはいけない。引用・スクリーンショット・
「本人がこう言っていた」の材料にしてはいけない
- 学習データは同意を明示的に取っていない会話。ログそのものと Discord の
user ID は公開していない
- 使える 147 個のラベルは
speakers.json にある (表示名と発言数だけ)
中身
3 epoch ぶんを全部置いてある。val の底は epoch 2 なので、まず epoch-2 を使う。
| val loss | ppl |
|---|
| 学習前 (Qwen3-0.6B-Base) | 3.3363 | 28.1 |
epoch-1 | 2.6060 | 13.5 |
epoch-2 | 2.5415 | 12.7 |
epoch-3 | 2.6008 | 13.5 |
epoch 3 で悪化するのはデータ律速で、長く回しても質は上がらない。
元の Qwen をどれだけ失ったか
「口調が移ったか」と「元の力が残っているか」は別の軸なので、学習に一切入って
いない普通の日本語でも測った (27,239 トークン / epoch-2)。
| 測る対象 | Qwen3-0.6B-Base | evex-ft-1 | 倍率 |
|---|
| 普通の日本語 (ppl) | 21.91 | 24.65 | 1.12x |
| この会話 (ppl) | 27.89 | 13.08 | 0.47x |
一般文は 12% 悪化しただけで、会話は半分。窓を伸ばしても倍率は動かない
(1024 / 2048 / 4096 で 1.12 / 1.14 / 1.15) ので、1024 で学習したことによる
長文脈の劣化は見えない。
ただし「説明する」レジスタは失っている。 base に git rebase と merge の違いって何
と聞くと一応 git の話をするが、こちらは まじ? と返す。雑談の相手としては自然に
なり、説明役としては使えなくなる — それが狙った取引。
使い方
素の transformers で動く。独自トークンは1つも足していない — 足すとその埋め込み
だけ未学習から始まるので、名前: 本文 という事前学習で大量に見ている形をそのまま使う。
1import torch
2from transformers import AutoModelForCausalLM, AutoTokenizer
3
4path = "tako080614/evex-ft-1"
5tok = AutoTokenizer.from_pretrained(path, subfolder="epoch-2")
6model = AutoModelForCausalLM.from_pretrained(path, subfolder="epoch-2", dtype=torch.float32)
7model.eval()
8
9# 学習時と同じ形。1行目はチャンネル、以降が `名前: 本文`、末尾に喋らせたい人を置く
10prompt = "#ch2\nたこ: これバグってる?\nあかり:"
11
12ids = tok(prompt, return_tensors="pt")
13out = model.generate(**ids, max_new_tokens=64, do_sample=True, temperature=0.9,
14 top_k=40, min_p=0.05, repetition_penalty=1.1,
15 pad_token_id=tok.eos_token_id)
16print(tok.decode(out[0], skip_special_tokens=True)[len(prompt):])
プロンプトの形
#ch2 ← チャンネル。#ch0..#ch15 か #other (上位16で全体の 97%)
たこ: これバグってる? ← 名前を持つ147人は表示名
A: どこで止まってる? ← それ以外は A..H / Z の相対の役 (会話ごとに振り直す)
あかり: ← 末尾に置いた人として続きを書く
| 記法 | 意味 |
|---|
#ch0〜#ch15 / #other | チャンネル。発言数の多い上位16に番号が付く |
名前: | 200発言以上の147人 (人間の発言の 96.6%)。speakers.json にある |
A: 〜H: / Z: | 147人の外。会話ごとの相対の役で、個人には紐づかない |
[画像] [動画] [ファイル] 等 | 添付だけの発言 (17,889件)。返答としては出さないよう損失から外してある |
@名前 | 返信先 |
同じ人が続けて喋ることがある。 学習データでは話者の塊のうち 27.4% が2連続以上
(2連続 17.8% / 3連続 5.6%) なので、モデルもそう書く。1発言だけ欲しいなら次の
名前: で切る。素の日本語形式には終端トークンが無いので、放っておくと
max_new_tokens を必ず使い切る。
147人の外の人になりきらせる
窓の先頭にその人の別の会話での発言を並べて、続きを書かせる。学習時に同じ形を
入れて (persona priming / 8,677会話 / その位置は損失から外す) あるので、
「先頭のブロックは条件、続きが予測対象」という形をモデルが知っている。
#ch0
A: これ動いた ← 別の会話から持ってきた A の発言
A: まあいけるやろ
B: これバグってる?
A: ← ここを書かせる
数字
| |
|---|
| ベース | Qwen/Qwen3-0.6B-Base (596,049,920 params) |
| 学習トークン | 10,089,887 (18,078 会話 / val 436 会話) |
| 損失から外した | 478,501 (4.7%) — 添付・URL・@名前 だけの本文と priming 位置 |
| 窓 | 1024 (会話を EOS で継いで詰める / パディングしない) |
| 学習 | 3 epoch / lr 5e-5 / cosine / warmup 3% / AdamW 8bit |
| fp16 + fp32 master weights / batch 1 × accum 16 (実効 16,384 tok/step) |
| ハードウェア | Kaggle T4 (16GB) / 峰 12.8GB / 約 6.5 時間 |
| 語彙 | 151,936 (Qwen のまま。増やしていない) |
Base を選んだのは Instruct だとアシスタントの口調が焼き付いているから。
1000万トークンでは上書きしきれず、「〜でしょうか」が残る。
できること / できないこと
できる: そのサーバーの口調、147人の読み分け、ネットスラング、短い応答、
名前を持たない人の口調 (例を渡せば)
できない: 事実、計算、翻訳、指示に従うこと、長い整合性
固有名詞は形だけ真似て中身が合わない (Cloudflare Codex のように既知の語を
組み替える)。事実として読むものではない。
ライセンス
ベースは Qwen3-0.6B-Base (Apache-2.0) の派生。学習データは非公開の私的な会話なので、
再配布・商用利用は想定していない。上の「表示名が重みに入っている」を必ず読むこと。