--- language: - ja license: apache-2.0 library_name: mlx tags: - mlx - apple-silicon - japanese - text-generation - from-scratch datasets: - HuggingFaceFW/fineweb-2 - globis-university/aozorabunko-clean - kunishou/oasst1-89k-ja - llm-jp/oasst2-33k-ja - llm-jp/magpie-sft-v1.0 - Aratako/Magpie-Tanuki-8B-97k pipeline_tag: text-generation --- # 3LM-MLX M1 Max (64GB) 1台で、一晩で事前学習から作った日本語の小さな言語モデルです。 ## 概要 | 項目 | 値 | |---|---| | パラメータ数 | 35,658,240 | | 非埋め込みパラメータ | 19,274,240 | | 語彙 | 32,000 (SentencePiece unigram / byte fallback) | | 文脈長 | 512 | | 層 / 次元 / ヘッド | 6 / 512 / 8 | | 構成 | RoPE / RMSNorm / SwiGLU / bias なし / weight tying | | 事前学習トークン | 367,607,808 | | 事前学習コーパス | 1,199,015,862 文字 | | 学習環境 | Apple M1 Max 64GB / MLX | ## 評価 同じサンプリング条件 (temperature 0.8 / top_k 40 / repetition_penalty 1.15 / seed 777) で測っています。 | 指標 | 3LM-MLX | 前作 (2LM-MLX) | 差 | |---|---|---|---| | bits/char (低いほど良い) | 2.801 | 2.540 | +0.261 (悪化) | | 反復率 (低いほど良い) | 0.300 | 0.100 | +0.200 (悪化) | | 主題保持率 (高いほど良い) | 0.667 | 0.733 | -0.066 (悪化) | | 破綻率 (低いほど良い) | 0.000 | 0.000 | +0.000 (変化なし) | 検証セット: `holdout_clean.txt` (220 行)。学習データから除いたうえで、**部分一致でも混入していないことを検査してから**測っています。 ### 検証セットを変えると、勝敗が変わります 上の表は「公開データ由来の会話」で測ったものです。前作はその公開データで**事前学習した**モデルなので、そこは前作の得意分野にあたります。土俵を変えて、同じ bits/char (低いほど良い) で並べます。 | モデル | A 公開データ由来の会話 | B Web文+青空文庫 | |---|---|---| | 2LM 13.81M | 2.540 | 6.481 | | 3LM 35.66M 事前学習のみ | 3.381 | 3.680 | | 3LM 35.66M SFT済み | 2.801 | 4.651 | | 3LM 35.66M 口調あり | 3.154 | 4.901 | 一般的な日本語の文 (土俵B) では前作を大きく上回ります。**bits/char は分母が文字数なので、語彙の大きさが違うモデル同士でも比べられます。** ## 使い方 ```bash pip install mlx numpy sentencepiece ``` ```python from huggingface_hub import snapshot_download from src.generate import load_bundle, chat_stream path = snapshot_download("GeneLab/3LM-MLX") model, tokenizer = load_bundle(path) for piece in chat_stream(model, tokenizer, [], "日本の首都はどこですか"): print(piece, end="", flush=True) ``` `load_bundle` と `chat_stream` は学習に使ったリポジトリ (https://github.com/hiroki-abe-58/3LM-MLX) に入っています。 ## 学習の流れ 1. **事前学習**: FineWeb2 の日本語 + 青空文庫から作ったコーパスで、次のトークンを当てる学習 2. **SFT (指示学習)**: 対話データで書式を合わせる。損失は `<|assistant|>` より後ろと `<|end|>` だけに掛けています (instruction masking) SFT で損失を数えたトークンの割合: 77.2% (会話 57,434 件) ## 学習データと帰属表示 ### 事前学習 | データ | ライセンス | 使った量 | |---|---|---| | [HuggingFaceFW/fineweb-2](https://huggingface.co/datasets/HuggingFaceFW/fineweb-2) (`jpn_Jpan`) | **ODC-By 1.0** | 1,080,000,054 文字 (90.1%) | | [globis-university/aozorabunko-clean](https://huggingface.co/datasets/globis-university/aozorabunko-clean) | **CC BY 4.0** | 119,015,882 文字 (9.9%) | FineWeb2 は Common Crawl から作られたデータセットで、ODC-By 1.0 に従い帰属を表示します。青空文庫版 (globis-university/aozorabunko-clean) は CC BY 4.0 です。どちらも継承条件 (ShareAlike) が無いため、この重みを Apache-2.0 相当で配布できます。 再現性のため、使用した revision と各シャードの SHA256 を構築スクリプトの manifest に記録しています (FineWeb2 `af9c13333eb9` / 青空文庫 `42a9c9c0f1d6`)。コーパス本体は再ホストせず、スクリプトと manifest で再現できる形にしています。 適用したフィルタ: 日本語文字比率 70% 以上 / 200〜20,000文字 / 定型文とエラーページの除去 / 重複除去 / 同一並びの繰り返し検出。 ### SFT | データ | ライセンス | |---|---| | [kunishou/oasst1-89k-ja](https://huggingface.co/datasets/kunishou/oasst1-89k-ja) | Apache-2.0 | | [llm-jp/oasst2-33k-ja](https://huggingface.co/datasets/llm-jp/oasst2-33k-ja) | Apache-2.0 | | [llm-jp/magpie-sft-v1.0](https://huggingface.co/datasets/llm-jp/magpie-sft-v1.0) | Apache-2.0 | | [Aratako/Magpie-Tanuki-8B-97k](https://huggingface.co/datasets/Aratako/Magpie-Tanuki-8B-97k) | Apache-2.0 | 継承条件のあるデータ (CC BY-SA など) は、配布ライセンスの整合が崩れるため意図的に使っていません。 ## 制限 - **35,658,240 パラメータ**しかありません。事実を答える能力はほとんど期待できません。知識の参照には使えません - 学習データの大半が Common Crawl 由来のウェブ文書なので、**そこに含まれる偏りや不適切な表現を引き継いでいる可能性があります** - 青空文庫を約10%混ぜているため、文語的な言い回しが出ることがあります - 商用利用の可否は、上記データセット各々のライセンスもご確認ください - 事前学習コーパスは Common Crawl 由来のため、メールアドレスや電話番号が含まれています。学習後に prefix attack で 60 件試したところ、**そのまま復元できたものはありませんでした** (コーパスを1周未満しか読んでいないため)。ただし、より強い攻撃で引き出せない保証はありません ## ライセンス - 重み: Apache-2.0 相当 - 学習コード: MIT (https://github.com/hiroki-abe-58/3LM-MLX) - 学習データの帰属: 上記のとおり (ODC-By 1.0 / CC BY 4.0 / Apache-2.0) ## 実測値のメモ - 1トークンあたり **2.101 文字** (語彙 32,000 / ウェブ文書) - コーパス 1,199,015,862 文字 = 570,676,120 トークン (うち学習に使ったのは 569,281,544)