Downloads · 30 days
37
18% of all-time downloads
tako080614/evex-3
evex-3 is a text generation model from tako080614. Use it when you need the model to write or continue text. It is set up for pytorch. The card lists the license as mit.
ある Discord サーバーの過去ログ 94万件だけで、tokenizer からゼロで作った 15.74M パラメータの言語モデル。事前学習済みの重みは1つも使っていない。
Downloads · 30 days
37
18% of all-time downloads
All-time downloads
211
Public
Parameters
15.7M
425 MB on disk
Likes
0
Public
Click a slice to open those files.
.safetensors62.9 MB · 100%
From the Hugging Face model README
ある Discord サーバーの過去ログ 94万件だけで、tokenizer からゼロで作った 15.74M パラメータの言語モデル。事前学習済みの重みは1つも使っていない。
同じ系統の兄弟 — evex-1 / evex-2(どちらも 5.87M)。 Qwen3-0.6B に同じログを追加学習した別系統もある (evex-ft-1 / ft-2 / ft-3)。
<|s0|> から <|s146|> は実在の人ひとりひとりに対応する。
つまりこのモデルは特定の人になりきって書ける。
speakers.json は順位と発言数だけ)evex-2 のコーパスには、evex-ft-2 / ft-3 で測って効いた工夫がひとつも入っていなかった。 あちらは全部コーパス側の話なので、記号に翻訳してそのまま持ち込んだ。
| evex-2 | evex-3 | |
|---|---|---|
| 話者 | 48人(発言の 85.3%) | 147人(96.6%) |
| 返信 | <|re|> の真偽だけ(相手を捨てていた) | <|re|><|sM|> で相手も |
| 窓 | 15分 / 20件 / 1200字 | 60分 / 60件 / 3600字 × 3通りの切り方 |
| 噛み合いの重み付け | なし | train の 12.5% |
| 長い発言の重み付け | なし | train の 24.5% |
| context | 512 | 1024 |
| 学習トークン | 6,479,221 | 23,950,617(3.70倍) |
| パラメータ | 5,865,984 | 15,735,168 |
返信先を残したのが一番大きい。 113,001 件の返信のうち 94,729 件で相手が分かる。 賑やかなチャンネルでは「誰に答えたか」が噛み合いの信号そのもので、evex-2 は そこを捨てていた。
**窓の切り方を3通りにして 2.08 倍に増やしてある。**新しい情報は増えない (同じ発言が違う位置・違う文脈長で出るだけ)ので、1 epoch が evex-2 の約2 epoch にあたる。開始位置をずらす方式は効かなかった(36,647 窓のうち 35,858 が同じ本文。 窓は主に沈黙時間で切れるので、読み始める位置を変えても境界が動かない)。
同じコーパスで 5.87M も回してある(evex-2 と同じ形)。良くなった分がコーパス由来か 大きさ由来かを分けるため。このモデル自身の val を同じ尺度で測った値を地の値にする。
匿名の役 <|b|>(bot の既定経路 / n=60)
| 対照 5.87M | evex-3 15.74M | 地の値 | |
|---|---|---|---|
| 噛み合い(質問の語が返答に出る) | 38.3% | 41.7% | — |
| 20字以上で返す | 65.0% | 58.3% | 31.2% |
| 平均の長さ | 39字 | 29字 | 19字 |
| 未知語 | 19.6% | 9.8% | 14.9% |
| 逐語コピー | 3.3% | 10.0% | — |
| 敬体 | 3.3% | 5.0% | 3.0% |
名前持ち <|s0|>(n=60): 噛み合い 23.3% / 20字以上 53.3% / 平均 35字 /
未知語 6.6% / 逐語コピー 15.0%
記号だけの返答は 0%(evex-2 と同じ。<url> や <file> を損失から外してある)。
実際に出てくるもの(samples.txt に epoch 5 のぶんが入っている):
<|s0|>rebase 疲れた<|s3|> → <|re|><|s5|>codexのレートリミット来たから
codexに課金してclaude codeのレートリミット来たから
<|a|>これバグってる?<|a|> → いやこれ普通にtry catchするからtry catchでエラー起きそうで
<|a|>TCP と UDP どっちが速いん<|b|> → TCPとかSPAの関係で外部環境を動かそうとしたら
Chromebookが起動しなくて良いよ...
返信先を自分で書く。<|re|><|s5|> のように「誰に返しているか」を出力に含める。
読む側は <|re|> と続く話者トークンを落としてから本文を取ること
(相手のトークンを「次の話者」と読むと本文が丸ごと落ちる)。
噛み合いは +3.4pt だが、逐語コピーが 3 倍になった。24M トークンに対する Chinchilla 最適は 1.21M パラメータなので、5.87M で既に 5 倍・15.74M で 13 倍過剰。 効いたのはコーパスであってサイズではない。
参考: 同じ質問・同じ匿名の役で Qwen3-0.6B 追加学習の系統は ft-1 20% / ft-2 34% / ft-3 30%。 38倍小さいこのモデルの方が噛み合っている(ただし事実の正しさは別の話で、 どちらも当てにならない)。
| パラメータ | 15,735,168(埋め込み 1.57M + 8層) |
| 形 | d_model 384 / 8層 / 6 head / context 1024 / RoPE + RMSNorm + SwiGLU + weight tying |
| 語彙 | 4,096(ログから作った sentencepiece BPE) |
| 学習トークン | 23,950,617 / 145,202 会話 |
| 学習 | 5 epoch / lr 1e-3 / cosine / AdamW / fp16 + fp32 master |
| val loss | 4.0741(記号を外した尺度)/ 素の val 4.1557 |
| ハードウェア | Kaggle T4 / 54,556 tok/s / 約 37 分 |
epoch ごとの val: 4.4115 → 4.1712 → 4.0927 → 4.0769 → 4.0741。 epoch 3 は逐語コピーが 11.7% と低いが、既定経路の噛み合いが 31.7% しか無いので epoch 5 を採った。
**val は evex-1 / evex-2 と直接比べられない。**コーパスも tokenizer も違う。 比べられるのは同じ v4 で回した 5.87M との間だけ。
外部データは使っていない。全部このサーバーのログ。
| 読んだ発言 | 945,009(うち bot 357,376 を除外) |
| 会話 | 18,806 → 窓の切り方3通りで 38,106(同じ本文 17,373 は落とした) |
| 噛み合った箇所 | 23,414 を ×2 |
| 長い発言(40字以上) | 30,134 を ×2 |
| 語彙 | 4,096(制御12 + 話者147 + 役8 + バイト等259 / 2.29 文字per token) |
| val | 最後の14日 436 会話。train と本文が同じものは外してある |
切り出しの割合は evex-ft-2 / ft-3 で測って効いた値(12.3% / 25.6%)に合わせて 周回数を自動で決めている。多すぎると窓の中身が3〜4行の短い会話ばかりになる。
transformers では動かない。素の PyTorch で読む。
import json, torch, sentencepiece as spm
from safetensors.torch import load_file
from huggingface_hub import snapshot_download
path = snapshot_download("tako080614/evex-3")
cfg = json.load(open(f"{path}/config.json"))
sp = spm.SentencePieceProcessor(model_file=f"{path}/tok.model")
state = load_file(f"{path}/model.safetensors")
state["head.weight"] = state["embed.weight"] # tie_word_embeddings
# model.py は https://github.com/tako0614/sakana の scripts/llm/model.py
from model import Config, MicroLM
model = MicroLM(Config(**{k: cfg[k] for k in
["vocab_size", "n_layers", "d_model", "n_heads", "context", "dropout", "attn_dropout"]}))
model.load_state_dict(state)
model.eval()
prompt = "<|conv|><|a|>これバグってる?<|s0|>"
ids = torch.tensor([sp.encode(prompt, out_type=int)])
out = model.generate(ids, max_new_tokens=80, temperature=0.9, top_k=40,
stop_id=sp.piece_to_id("<|end|>"))
print(sp.decode(out[0].tolist())[len(prompt):])
<|conv|><|s0|>これバグってる?<|s3|><|re|><|s0|>どこで止まってる?<|s0|>
↑147人の誰か ↑別の人 ↑<|s0|> への返信 ↑ここの続きを書かせる
<|s0|>..<|s146|>(固有)と <|a|>..<|h|> / <|z|>(会話ごとの相対)<|re|> のあとに相手のトークンを置く。相手が会話に居ないときは
<|re|> だけにする(学習でもそうしてある)<|end|> で会話が終わる。<url> <file> <mention> <channel> <time> は
正規化が作った記号で、損失から外してあるので自分では書かないできる: このサーバーの口調、147人の読み分け、会話の交代
できない: 事実、計算、翻訳、指示に従うこと
15.74M しか無いので内容は当てにならない。狙えるのは「話を受けて、それらしい形で、 このサーバーの口調で返す」まで。
重みは MIT。学習データは非公開の私的な会話なので、上の「147人の話者が重みに 入っている」を必ず読むこと。