3行でいうと
- mlx-lmのコマンドは
mlx_lm.lora。モデルが量子化済みならQLoRA、そうでなければ普通のLoRAになります。 - 学習データは
train.jsonl(1行に1例)で、chat・tools・completions・textの4形式です。 - 公式文書の32GB向けの例は、7Bモデル、batch-size 1、num-layers 4で、M1 Maxで約250トークン/秒です。
- メモリを減らす手は、QLoRA、バッチ縮小、層数削減、短い例、勾配チェックポイントの5つです。
この記事は、実際に使って確かめた記録ではありません。この記事は公式の文書や論文を読んでまとめたものです。数字の計算は、設定ファイルの値から僕らが行ったものです。
先に結論
Macで「自分のデータでモデルを少し賢くする」には、mlx-lmの mlx_lm.lora が公式の入口です。モデル全部を学習し直すのではなく、モデルの横に小さな追加部品(アダプター)を付けて、そこだけを学習します。これがLoRA(Low-Rank Adaptation、低ランク適応)です。
公式文書は、メモリ32GBのマシンで「そこそこ速く動く」例として、7Bモデルを最小限の設定(バッチ1、4層)で動かす例を挙げています。それより大きいモデルや長い学習データについて、公式文書に目安の数字はありません。
見立てです。32GBのMacで7B前後は試せる範囲だと読めますが、確かめてはいません。最初は、小さいモデル(公式の設定例が使っているのは1Bクラス)と数百行のデータで、手順とメモリの減り方を体感してから広げるのが安全だと思います。
前提:何をする話か
- ファインチューニング(微調整)は、すでにできあがったモデルに、追加のデータで学習をさせることです。口調や出力の形式、特定の業務の言い回しを覚えさせる用途で使われます。
- LoRAは、元のモデルの重みを凍結(固定)したまま、各層に小さな行列のペアを足して、そこだけを学習する方法です。論文(Huら、2021年、arXiv:2106.09685)の要旨では、GPT-3 175Bをアダムで普通に微調整する場合と比べて、学習する数を1万分の1、GPUメモリを3分の1にできるとされています。
- QLoRAは、元のモデルを4ビットに圧縮(量子化)した状態でLoRAを行う方法です。論文(Dettmersら、2023年、arXiv:2305.14314)の要旨では、65Bモデルを48GBのGPU1枚で、16ビットで微調整した場合の性能を保ったまま学習できるとされています。
- アダプターは、学習で得られる小さな追加部品のファイルです。元のモデルとは別に保存され、使うときに重ねます。
- JSONLは、1行に1つのデータを書くファイル形式です。
mlx-lmとは
公式READMEによると、mlx-lmは、Apple siliconで、MLX(Appleの機械学習の枠組み)を使って、文章生成と大規模言語モデルの微調整をするPythonパッケージです。低ランク(LoRA)と全体の微調整の両方に対応し、量子化したモデルも扱えます。入れ方は pip install mlx-lm(condaも可)です。PyPIで見える最新版は0.32.0(2026年10月1日公開)で、Pythonは3.11以上を要求します。
微調整に必要な追加部品は、pip install "mlx-lm[train]" で入ります。
手順:公式文書の流れ
1. 学習データを用意する
--data に、train.jsonl を入れたフォルダを指定します。valid.jsonl(検証用)は任意で、あれば学習中に検証の損失(loss)が報告されます。学習後の評価(--test)には test.jsonl が要ります。公式文書の注意書きでは、1つの例は必ず1行に収め、複数の例を1行に入れたり、1つの例を複数行に割ったりしてはいけません。
形式は4つです。ファイルの中身から自動で判定されます。
| 形式 | 1行の中身 | 使いどころ(見立てです) |
|---|---|---|
| chat | messages(役割と本文のリスト) |
会話の口調や応答の形を覚えさせる |
| tools | messages と tools(関数の定義) |
道具の呼び出しの形を覚えさせる |
| completions | prompt と completion |
質問と答えのペア |
| text | text だけ |
自分で整形した文章をそのまま学習させる |
公式文書は、迷ったら chat か completions から始めるよう勧めています。chat・tools・completions では、モデル固有の「チャットテンプレート」(会話を並べる決まった書式)が自動で当てはまります。
2. 学習する
公式文書の例です。この記事では、実行していません。
mlx_lm.lora \
--model <path_to_model> \
--train \
--data <path_to_data> \
--iters 600
--model には、Hugging Faceのリポジトリ名か、手元のフォルダを指定できます。--model が量子化済みのモデルならQLoRA、そうでなければ普通のLoRAになる、と公式は書いています。
結果は既定で adapters/ に保存されます。--adapter-path で場所を変えられ、--resume-adapter-file で途中から再開できます。YAML設定ファイルは -c で渡せ、コマンドラインの指定が優先されます。
3. 評価して、試しに生成する
--test を付けると、テスト用データでの損失から perplexity(困惑度、低いほど予測が当たっている)を出します。生成は mlx_lm.generate に --adapter-path を付けます。
4. アダプターをモデルに溶かす(fuse)
mlx_lm.fuse で、アダプターを元のモデルに統合した新しいモデルができます(既定の保存先は fused_model/)。Hugging Faceへのアップロードもできます。GGUF形式への書き出し(--export-gguf)もありますが、公式文書は「MistralとMixtralとLlama系で、fp16の場合に限る」と書いています。
設定の既定値(ソースコードで確認)
mlx_lm/lora.py の CONFIG_DEFAULTS(2026年10月8日にmainブランチで確認)の主な値です。
| 項目 | 既定値 | 意味 |
|---|---|---|
| fine_tune_type | lora | lora・dora・full から選ぶ |
| optimizer | adam | 学習の更新方法 |
| num_layers | 16 | 後ろから数えて何層を学習するか(-1で全部) |
| batch_size | 4 | 一度に処理する例の数 |
| iters | 1000 | 学習の回数 |
| learning_rate | 1e-5 | 学習の速さ |
| max_seq_length | 2048 | 1つの例の最大トークン数 |
| grad_checkpoint | False | 勾配チェックポイント(後述) |
| lora_parameters | rank 8、scale 20.0、dropout 0.0 | LoRAの部品の大きさなど |
注意点が2つあります。まず、lora_parameters はコマンドラインでは指定できず、YAML設定ファイルでのみ変えられます(設定例のコメントに書かれています)。次に、公式のYAML例では対象を self_attn.q_proj と self_attn.v_proj(注意機構の2つの行列)に絞っていますが、keys を書かない場合、ソースコードの linear_to_lora_layers は、対象の層の中にある線形層をすべて自動で拾う作りに見えます。この記事は、実際に使って確かめた記録ではありません。
メモリの目安
Mistral 7Bで見る、学習する部品の数と重みの大きさ
僕らの計算です。Mistral-7B-v0.1の設定ファイル(Hugging Faceのconfig.json)は、隠れ層の幅4,096、層数32、中間層の幅14,336、KVヘッド数8(Keyの出力幅は1,024)です。パラメータ数は、Hugging Faceの情報で7,241,732,096個です。
重みの大きさ
BF16(1つ2バイト)なら約14.5GB、4ビット(1つ0.5バイト)なら約3.6GBです。4ビットの値は、量子化の細かい上乗せを含まない概算です。
LoRAで学習する数
LoRAは、入力幅×出力幅の行列1枚につき、rank×(入力幅+出力幅)個を足します。rank 8で計算すると、次のとおりです。
| 対象 | 1層あたり | 16層 | 全体に対する割合 |
|---|---|---|---|
| q_projとv_projだけ | 106,496個 | 約170万個 | 約0.02% |
| 注意機構の4つ+MLPの3つ(全部の線形層) | 655,360個 | 約1,049万個 | 約0.14% |
学習する数は、全体の1%にも届きません。QLoRAの論文は、7Bモデルで、学習する部品が約26MBなのに対して、4ビットの本体は5,048MBだったと報告しています。ただし、同じ論文は、メモリの大半は「活性化の勾配」(学習の途中で必要になる一時データ)で、部品の数を減らしても節約は小さい、とも述べています。
論文の数字
- LoRA論文:GPT-3 175Bで、学習時のVRAMが1.2TBから350GBになり、チェックポイントの大きさがrank 4・q/vのみの場合に350GBから35MBになる。
- QLoRA論文:16ビットで65Bを微調整すると780GB超のGPUメモリが要る。7B(バッチ1)で、LoRAの入力の勾配が567MB、勾配チェックポイントありなら1シーケンスあたり平均18MB。
公式文書の「32GB」の例
公式文書の「Memory Issues」節は、32GBのマシンで「そこそこ速く動く」例として、次を挙げています。公式文書の例です。この記事では、実行していません。
mlx_lm.lora \
--model mistralai/Mistral-7B-v0.1 \
--train \
--batch-size 1 \
--num-layers 4 \
--data mlx-community/wikisql
文書は、M1 Max(32GB)で、この命令が約250トークン/秒だったと書いています。データは wikisql(SQL生成のデータ)です。
見立てです。この例は量子化されていないモデルの名前を指しているので、上のルールどおりなら、普通のLoRAです。重みだけで約14.5GBあり、32GBの半分近くを占めます。残りにOSと学習中の一時データが入ることになります。文書に、このときの実際のメモリ使用量は書かれていません。
メモリを減らす5つの手
公式文書は、次の順に挙げています。
- QLoRA:量子化したモデルを使う。公式は、
convertに-qを付けて作る方法を案内しています。READMEにはmlx_lm.convert --model ... -qもあります。 - バッチを小さくする:
--batch-size(既定4)を2か1にする。遅くはなるが、メモリは減る。--grad-accumulation-steps Nで、メモリを増やさずに実質のバッチを大きくできる。 - 学習する層を減らす:
--num-layers(既定16)を8や4にする。メモリは減るが、データが多いと品質が下がることがある。 - 例を短くする:長い例ほどメモリを使う。区切れるなら、短い列に分けてファイルを作る。
- 勾配チェックポイント:
--grad-checkpoint。途中の値を保存せず、必要なときに計算し直すことで、メモリを節約して計算量を増やす方法。バッチや列が長いとき、あるいは小さい・量子化したモデルのときに、より効果がある、と公式は書いています。
もう一つ、READMEの「Large Models」節に、macOS 15以上で、モデルがメモリに対して大きいとき、sudo sysctl iogpu.wired_limit_mb=N でGPUが使える固定メモリの上限を上げられる、とあります。Nはモデルの大きさ(MB)より大きく、マシンのメモリ量より小さい値にします。学習のコード側でも、maybe_set_recommended_wired_limit で推奨値に設定する処理を呼んでいます。
判断の基準
見立てです。
- 目的が口調・出力の形式・社内用語なら、まずLoRAで試す価値があると思います。どこまで効くかは、公式文書が約束している範囲ではありません。
- メモリが足りないなら、手を打つ順番は、バッチ1、層数4、データを短く、勾配チェックポイント、QLoRAの順に試すのが分かりやすいと思います。品質に影響する手(層数、QLoRA)を後にするためです。
- 結果をほかの道具で使いたいなら、fuseのGGUF書き出しの条件(Mistral・Mixtral・Llama系、fp16)に当てはまるかを先に確認してください。それ以外のモデルでは、llama.cpp側の変換手順(別記事で扱います)を使うことになります。
よくあるつまずき
- 1例が複数行になっている:JSONLは1行に1例です。ツールの出力を整形して貼ると、壊れます。
- 文書とコードのずれ:LORA.mdの対応モデル一覧(Mistral、Llama、Phi2、Mixtral、Qwen2、Gemma、OLMo、MiniCPM、InternLM2)は古い可能性があります。READMEは、数千のモデルに対応し、未対応ならissueを出すよう案内しています。使いたいモデルが微調整に対応するかは、確認できていません。
- 長い例を入れる:
max_seq_lengthの既定は2048トークンです。それより長い例がどう扱われるかは、確認できていません。--helpと一度の小さな実行で確かめてください。
気をつけること
- この記事では、ここで紹介したコマンドを実行していません。出力の見え方、速度、メモリの実測値は確認できていません。
- 公式文書の「約250トークン/秒」は、M1 Max・32GB・特定のデータでの値です。ほかの機種・モデル・データには当てはまりません。新しい機種での値は、確認できていません。
- 学習中に画面に出る列は、損失・トークン/秒・学習済みトークン数です。ピークメモリは、コード上は記録され、ログ送信の仕組み(wandbなど)に渡されます。画面表示では確認できませんでした。
- 設定の既定値とバージョン(0.32.0)は、2026年10月8日時点のmainブランチとPyPIのものです。変わることがあります。
- 論文の数字は、それぞれの実験条件(GPT-3 175B、LLaMA 7B・65B、NVIDIAのGPU)のものです。Appleのチップの結果ではありません。
- LoRA・QLoRAの品質の話は、論文の主張です。
出典
- mlx-lm LORA.md(ml-explore/mlx-lm、Apple、2026年10月8日確認)
- mlx-lm README(ml-explore/mlx-lm、Apple、2026年10月8日確認)
- mlx_lm/lora.py(ml-explore/mlx-lm、Apple、2026年10月8日確認)
- mlx_lm/tuner/utils.py(ml-explore/mlx-lm、Apple、2026年10月8日確認)
- mlx_lm/tuner/trainer.py(ml-explore/mlx-lm、Apple、2026年10月8日確認)
- examples/lora_config.yaml(ml-explore/mlx-lm、Apple、2026年10月8日確認)
- mlx-lm(PyPI、2026年10月8日確認)
- LoRA: Low-Rank Adaptation of Large Language Models(arXiv:2106.09685、Huら、2026年10月8日確認)
- QLoRA: Efficient Finetuning of Quantized LLMs(arXiv:2305.14314、Dettmersら、2026年10月8日確認)
- Mistral-7B-v0.1 config.json(Hugging Face、Mistral AI、2026年10月8日確認)
更新履歴
- 2026年10月25日 書き方を直しました。
- 前:運営者が使っていないと読める書き方 → いま:「この記事は、実際に使って確かめた記録ではありません」。公式の資料を読んでまとめた記事で、使い心地は書いていない、という意味に直した
