h3-metal、Apple Silicon向けMiniMax-H3推論ライブラリ
本文の状態
日本語全文を表示中
詳細モードで約50分の本文を読めます。
同じ出来事の情報源
この情報源を基点に整理
TLDR AI
GitHub リポジトリ「h3-metal」は、Apple Silicon 上で MiniMax-H3 モデルをネイティブ推論可能にするプロジェクトであり、M3 Max や M5 Max 向けの性能最適化と動画生成機能の実装が進んでいる。
Continue in AI NEW LAB
このニュースを、実務の判断につなげる
AI NEW LABで、試したことや先に確認したい条件を共有できます。まずはログインなしで読めます。
AI NEW LABで論点を見るAI深層分析を開く2026年8月12日 22:29
AI深層分析
キーポイント
Apple Silicon 向けネイティブ推論の実現
このプロジェクトは Apple Silicon 上で MiniMax-H3 モデルを Metal を介してネイティブに実行可能にするものであり、M3 Max や M5 Max における性能とメモリ最適化が進行中である。
高度な動画生成機能の統合
プロンプトから動画や音声への生成、初回・最終フレーム条件付け、および順序付き参照画像(Ref2VA)による制御機能がエンドツーエンドで動作するよう実装されている。
効率的なインタラクティブセッション
CLI を介したインタラクティブモードでは、BF16 プロンプト条件付けやビデオデコーダーをメモリに保持し続けることで、異なるシードでの再生成時にロード時間を省略できる。
高速動画生成の設定
デフォルトのバランス設定では22フレーム・24fpsで約0.92秒の動画を生成し、各ノイズ除去段階後に中間フレームを表示する。--steps 20、--reuse 2、--layers 45などのパラメータにより計算時間とメモリ使用量を削減している。
表示オプションの機能
--show オプションは対応するグラフィカルターミナルで中間フレームをリアルタイム表示し、デフォルトではRetinaディスプレイ向けに2倍の解像度で描画される。この機能にはプレビューデコード時間と約10GiBのモデル一時記憶領域が必要だが、実行速度への影響はない。
重要な引用
Native MiniMax-H3 inference for Apple Silicon.
Prompt-to-video/audio, first/last-frame conditioning, and ordered Ref2VA image/video/audio references work end to end.
The session keeps the exact BF16 prompt conditioning, prepared DiT, and video decoder in memory
!refs lists the current order, !ref-remove N removes one entry, and !refs clear removes them all.
編集コメントを表示
編集コメント
MiniMax-H3 のような最新モデルを Apple Silicon で動作させるための技術的アプローチが詳細に示されており、ローカル環境での高品質動画生成の可能性をさらに広げる内容である。開発者は Metal を活用した最適化の手法から多くの示唆を得られるだろう。
Source Article
元記事を日本語で読む
本文に関係しない購読案内、埋め込み通知、サイト内プロモーションは除いています。
h3-metal
Apple Silicon 向けに MiniMax-H3 の推論をネイティブで実行するプロジェクトです。開発は機能ごとに段階的に進められており、まずホストとモデルのメタデータを確定させ、次に移植可能な Metal ブロックの互換性を実装します。その後、プロンプトエンコーディング、動画・音声への生成、最初/最後のフレーム条件付け、そして順序付き参照(ordered references)へと機能を追加していきます。
現在、プロンプトから動画や音声を生成する機能、最初と最後のフレームを条件とする機能、および Ref2VA 形式の画像・動画・音声参照を順序付けて利用する機能は、エンドツーエンドで動作しています。現在の開発焦点は、M3 Max および M5 Max における H3 固有の Metal パフォーマンス向上とメモリ最適化です。
チュートリアル
1. モデルの構築と確認
以下の例では、Hugging Face のスナップショットが ./MiniMax-H3 にあり、かつ PATH に FFmpeg と FFprobe が設定されていることを前提としています。
make -j8
mkdir -p outputs
./h3 --info -d ./MiniMax-H3--info オプションは、モデルのレイアウトを確認し、すべての重みをマッピングしたりメディアを生成したりすることなく、選択された Metal デバイスを出力します。完全な CLI リファレンスは ./h3 --help で確認できます。
-p を指定しない場合、同じバイナリが Iris スタイルの対話型セッションを開始します:
./h3 -d ./MiniMax-H3 --width 512 --height 512 --steps 6プロンプトを入力して番号付きの動画を生成します。セッション中は、正確な BF16 プロンプト条件、用意された DiT、およびビデオデコーダーがメモリ上に保持されるため、同じものを繰り返すことができます。
別のシードでプロンプトを実行すると、再読み込みやエンコードが不要になります。よく使うコマンドには !status、!seed random、!seconds 2、!show などがあります。
output.mp4 を保存し、!cache を使用します。完全な短縮リストについては !help を実行してください。 (原文の技術表記: !save output.mp4)
セッション内で最初のフレームと最後のフレームの条件付けが維持されます:
h3> !first opening.png
h3> !last ending.png
h3> The camera moves slowly around the subject.
!first clear または !last clear を使用してアンカーを削除できます。生成された動画は、起動時に表示されるセッションディレクトリに書き込まれます。
一般的な Ref2VA の条件付け画像には、!ref-image PATH を使用してください。画像は指定された順序で追加され、モデルに対して <Picture 1>、<Picture 2> といった形式で認識されます。ファイル名自体に意味はありません。
h3> !ref-image person.png
h3> Make the person shown in Picture 1 wave to the camera.
!refs コマンドは現在の順序を一覧表示し、!ref-remove N で特定の 1 つのエントリを削除でき、!refs clear を実行するとすべてが削除されます。Ref2VA の参照は混在させることはできません。
!first/!last アーバー。
2. 最初の高速動画を作成する
検証済みのバランス型プリセットから開始します。この設定では、24 fps で 22 フレーム(約 0.92 秒)を生成し、対応するグラフィカルターミナル上でノイズ除去の各遷移後に進行中の中間動画フレームを表示するとともに、フェーズごとの処理時間を出力します。
./h3 --profile \
-d ./MiniMax-H3 \
-p "A red fox walks through fresh snow in a pine forest. Medium tracking shot, natural winter light, realistic fur, soft footsteps and wind." \
--width 512 --height 512 \
--frames 22 --steps 20 \
--layers 45 --reuse 2 \
--show \
-o outputs/fox-fast.mp4これはあえて最も攻撃的な構成ではありません。
--steps 20はデフォルトの 20 回のノイズ除去パスを実行します。--reuse 2では、全 20 回ではなく 11 回の新鮮なノイズ除去器速度を計算し、スキップされた遷移を外挿処理します。--layers 45は、50 個あるトランスフォーマーブロックのうち 45 個を実行するため、処理時間と統一メモリの使用量を削減できます。
--showオプションは任意です。Kitty、Ghostty、iTerm2、WezTerm、Konsole の各グラフィカルプロトコルに対応しています。このオプションを指定すると、常駐するプレビュー VAE が読み込まれ、Euler 変換のたびに代表となる中間フレームが1枚表示され、最終的にすべての生成フレームが表示されます。
表示サイズはデフォルトで 2x に設定されており、macOS の Retina ディスプレイ上で画像が意図した論理サイズになるようにしています。HiDPI ではないディスプレイでは --zoom 1 を使用してください。これによりプレビューのデコードに時間がかかり、モデルの一時的なメモリ使用量が約 10 GiB 増加しますが、--show オプションなしで実行する場合は影響はありません。
--profileはオプションであり、生成パスを切り替えるものではありません。
最初の処理呼び出しでは、モデルの読み込みコストとファイルシステムキャッシュのコストも発生します。性能を比較する際は繰り返し実行を行い、マシンがウォーミングアップしている間はバリエーションを切り替えてください。このワークロードはサーマルスロットリングの影響を受けやすいためです。
非常に短い反復の場合は、4 回の拡散パスを直接リクエストしてください。
./h3 --profile \
-d ./MiniMax-H3 \
-p "A red fox walks through fresh snow in a pine forest. Medium tracking shot, natural winter light, realistic fur." \
--width 512 --height 512 --frames 22 \
--steps 4 --layers 50 --reuse 1 \
--show \
-o outputs/fox-four-step.mp4--steps N は常に正確に N 回の拡散パスを意味します。4〜7 パスは低予算比較で勝利したのと同じスケジュールを使用し、4 から 7 に増やすことで詳細度と動きが段階的に向上します。このような小規模な予算では --reuse 1 を維持して、要求されたすべてのパスでモデルを実行できるようにしてください。また、--show を使用すると、各パスごとにプレビューが表示されます。
多くの可視的なクリーンアップは長時間の実行の最後に発生するため、いくつかの末尾に重みのあるスケジュールが評価されました。しかし、これらは初期の構成更新をあまり保持できず、織り交ぜられたテクスチャや弱体化した動き、切り捨てられた色を生み出してしまいました。
採用されたモードでは、リリースされた線形ベースグリッドと1つの終端点を使用します。512ピクセル四方・22フレームの狐テストにおいて、選択された4パスの結果は、29パスの参照に対して0.556のフルビデオSSIMを達成しました。独立したサーファーテストでは0.547でした。
M5 Max における4パスのノイズ除去には約3.5秒かかりましたが、参照モデルでは26.4秒必要でした。
低メモリ実行を行う場合は --ssd-streaming を追加してください:
./h3 --profile \
-d ./MiniMax-H3 \
-p "A red fox walks through fresh snow in a pine forest." \
--width 512 --height 512 --frames 22 --steps 20 \
--layers 50 --reuse 1 --ssd-streaming \
-o outputs/fox-ssd.mp4これは変換や量子化を行わない元の BF16 チェックポイントを使用します。GPU が現在のブロックを実行している間に、2 つの DiT ブロックをメモリに保持し、次のブロックを SSD から読み込みます。
M5 Max において、追跡される DiT のストレージは、512 平方で約 36.5 GiB から 2.0 GiB に、864x480 では 2.1 GiB に減少しました。ウォームアップ状態の 50 ブロック順方向計算では、512 平方で 1.35 秒(参照の 2.49 秒に対し 84% 遅い)、864x480 で 2.14 秒(参照の 2.68 秒に対し 26% 遅い)となりました。これらは同じフルレジデンシー BF16 パスとの比較であり、両方のチェックで結果はバイト単位で同一でした。
2.0〜2.1 GiB という数値は、DiT の追跡テンソルストレージのみを示しており、システム全体の RAM ではありません。プロンプトエンコーディングと 2 つの VAE は別々のフェーズで実行されるため、それらの最大ピークがこれに直接加算されるわけではありません。OS、メディアバッファ、出力解像度にはまだ余裕が必要です。
--show を使用するとプレビュー用の VAE が常駐し、さらに約 10 GiB 追加されます。最低限のメモリ使用量を実現するには、これを省略してください。
SSD ストリーミングは、明示的なメモリと速度のトレードオフであり、デフォルトでは無効です。--use-int8-row-fc2 オプションとは併用できません。インタラクティブなセッションでは、!ssd-streaming on を使用して有効化してください。
3. リファレンス品質への接近
品質を評価する際は、一度に一つの制御項目を変更してください。まずはすべてのレイヤーを復元し、次にすべてのディノイザー評価を適用します。最後に、デフォルトの 20 パススケジュールから、より低速な 50 パスのリファレンス設定へ引き上げます。
./h3 --profile \
-d ./MiniMax-H3 \
-p "A red fox walks through fresh snow in a pine forest. Medium tracking shot, natural winter light, realistic fur, soft footsteps and wind." \
--width 512 --height 512 \
--frames 22 --steps 50 \
--layers 50 --reuse 1 \
-o outputs/fox-close.mp4デフォルトは --steps 20 --layers 50 --reuse 1 ですが、このクローズドパスでは明示的に --steps 50 を指定してください。これは 50 ブロック分の完全な逆ノイズ除去を 50 回実行するもので、デフォルトよりもはるかにコストがかかりますが、高速モードで被写体や解剖構造、動き、構図が変わってしまった場合の正しいオラクルとなります。
MLX を使用する場合、数値的なピクセルレベルでの完全な一致は期待できません。乱数生成エンジンと実行エンジンの違いによるものです。ただし、描画されるコンテンツや動きが一致しているはずです。
4. スピード/品質プリセットの選択
これらのコントロールは、特に注記がない限り独立しています。
| 制御 | 低速リファレンス | デフォルト | アグレッシブ | 主要な影響要因 |
|---|---|---|---|---|
| ノイズ除去パス数 | --steps 50 | --steps 20 | --steps 4..7 | 数値は実際のノイズ除去パス数を示します。 |
| デノイザー全体の再利用 | --reuse 1 | --reuse 2 | --reuse 3 | 20 ステップの場合:新鮮な DiT 評価はそれぞれ 20、11、または 8 回。 |
| アクティブな DiT ブロック数 | --layers 50 | --layers 45 | --layers 40 | ブロック数を減らすと、計算量とレジスタントなトランスフォーマー重みが削減されます。 |
| コア残差の再利用 | --core-reuse 1 | --core-reuse 4 | --core-reuse 6 | パッチ/ヘッドの処理を毎ステップ更新しますが、高コストなコアの計算頻度は下げます。 |
| トークン削減 | オフ | オプション | --token-reduction | 中央ブロック内の水平方向のビデオトークンをペアリングします。高速化されますが、構成が変わる可能性があります。 |
| 内部キャンバスサイズ | 出力サイズ | 384x384(512 正方形出力用) | 320x320 | DiT/VAE を小さいサイズで実行し、その後 vImage でアップスケーリングします。 |
M5 では、--use-int8-row-fc2 オプションが FC2 の各行に 1 つの活性化スケーラーを使用し、単一のフル幅 TensorOps 演算を行います。これは数値的な保守性がグループ化された int8 よりも低いため、オプションとなっています。逆数のテストでは、完全なデノイザーのフォワードパスが約 2.6% 短縮されました。4 ステップの fox および surfer の動画では結果は同等でした。
被写体、設定、および動き(フル動画の SSIM はそれぞれ 0.919 と 0.828)。インタラクティブセッションでは !int8-row-fc2 on を使用してください。
--reuse と --core-reuse は排他的なオプションです。レイヤーの薄化は、どちらか一方と組み合わせて利用できます。
最初のコマンドを高速化しつつ出力解像度を維持するには、トークン削減を追加します。
./h3 --profile \
-d ./MiniMax-H3 \
-p "A surfer riding inside a sharp blue ocean wave, one rider and one white board, realistic spray." \
--width 512 --height 512 --frames 22 --steps 20 \
--layers 45 --reuse 2 --token-reduction \
-o outputs/surfer-fast.mp4検証済みの 512×512 の正方形形状において、トークン削減により、IT M5 Max 上での 45 layers + reuse 2 のノイズ除去プロファイルの処理時間が 16.69 秒から 12.60 秒に短縮されました。独立した「fox」と「surfer」のレンダリング結果は整合性を保ちましたが、構成要素が元のパスからより大きく乖離する可能性があります。
アグレッシブなプレビューを行う場合は、内部で 320×320 の解像度でレンダリングし、後で要求された 512×512 の出力にアップスケーリングします:
./h3 --profile \
-d ./MiniMax-H3 \
-p "A red fox walking through snow, realistic, tracking shot." \
--width 512 --height 512 \
--render-width 320 --render-height 320 \
--frames 22 --steps 20 --layers 40 --reuse 3 \
-o outputs/fox-aggressive.mp4この組み合わせにより、検証では明確に認識できる 22 フレームのキツネが生成されました。ただし、細部の描写が失われたり、構図が変わってしまう可能性があります。--token-reduction を --layers 40 と --reuse 3 の両方に追加してはいけません。この組み合わせをテストした際、色のリング現象(カラーリング)、輪郭の乱れ、手足が二重に見えるゴースト化が発生しました。
全体速度の再利用に対する代替案として、この手法では各遷移時にタイムステップ依存のパッチと出力ヘッドを常に新鮮な状態に保ちます。
./h3 --profile \
-d ./MiniMax-H3 \
-p "A surfer riding a blue ocean wave." \
--width 512 --height 512 --frames 22 --steps 20 \
--layers 45 --core-reuse 4 \
-o outputs/surfer-core-reuse.mp4--core-reuse 6 は、積極的なプレビューとしてのみ使用してください。6 より大きい値は、検証プロセスで主題の忠実性が失われるため公開されていません。
5. 解像度と再生時間の選択
幅と高さはそれぞれ 32 の倍数である必要があり、最小値は 32 です。また、両者の積は 768 * 1344 ピクセルを超えてはいけません。これらは機械的な制限事項であり、すべての微小なキャンバスで良好なモデル品質が得られることを保証するものではありません。H3-Base は 768p モデルです。
| キャンバス | 現在のガイダンス |
|---|---|
512x512 | 最も安全な開発サイズ;複数のプロンプトで反復検証済み。 |
768x768 | 高品質な正方形出力を検証済み;ただしコストが大幅に増加。 |
1344x768, 768x1344 | 768p クラスの横長/縦長の制限としてリリース済み。 |
1024x768, 768x1024 | 有効な 4:3 および 3:4 の 768p クラスキャンバス。 |
384x384 (内部 512x512) | 高速品質のスケーリングポイントとして検証済み。 |
320x320 (内部 512x512) | 積極的なスケーリングポイントとして検証済み。 |
256x256 | 自動低解像度 RoPE 適応を備えたネイティブ高速プレビューキャンバス。 |
高速なネイティブ 256 平方ピクセルのプレビューには、以下のコマンドを使用してください。
./h3 -d ./MiniMax-H3 \
-p "A red fox walks through fresh snow in a pine forest." \
--width 256 --height 256 \
--frames 22 --steps 20 \
--layers 50 --reuse 1 \
-o outputs/fox-256.mp4256 平方ピクセルでは、H3 の有効な空間トークングリッドは 8x8 に過ぎず、細部の描写や複雑な構成を表現する余地が限られます。このサイズでは H3 が自動的に空間 RoPE(回転位置埋め込み)座標を半分にし、長いフォックスの生成における繰り返しの格子状アーティファクトを除去し、独立したポートレートでもトークン数や実行時間を増やすことなく一貫性を保ちます。
比較検証のためにリリース版または MLX 版の座標に戻す場合は --use-reference-rope を使用してください。このサイズではトークン削減機能はオフのままにしておいてください。ネイティブ 128 平方ピクセルはまだサポートされていません。4x4 のトークングリッドでは、RoPE を調整しても認識可能な被写体を再現できませんでした。
--render-width と --render-height はセットで設定する必要があり、出力のアスペクト比と一致させる必要があります。また、これらの値は出力の解像度を超えてはいけません。モデルと VAE は内部サイズを使用しますが、ターミナルフレームやエンコードされた動画はリクエストされた出力サイズを維持します。
H3 は 24 fps で動作し、フレームのリクエストは 5 + 17*n に切り上げて調整されます。
--seconds N を指定して時間ベースの要求を行うか、--frames N で直接フレーム制御を行うかのいずれかを選択してください。両方のオプションを同時に使用することはできません。小数点以下の秒数も受け付けられます。秒数は 24 fps で変換され、次に有効な H3 の時間形状に合わせて切り上げられるため、--seconds 10 を指定すると 243 フレーム(10.125 秒相当)が生成されます。
| フレーム数 | 概算動画再生時間 |
|---|---|
| 22 | 0.917 秒 |
| 39 | 1.625 秒 |
| 56 | 2.333 秒 |
| 107 | 4.458 秒 |
| 243 | 10.125 秒 |
| 362 | 15.083 秒 |
開発には短いクリップが役立ちます。公開されたワークフローは、概ね 4〜15 秒の動画向けに設計されています。
--frames 23 のように指定した場合、任意の時間形状を生成するのではなく、39 フレームに丸められます。
6. プロンプトの改善
短いプロンプトでも動作しますが、公開されたシステムでは Context-IR 形式の説明が期待されます。被写体、アクション、設定、カメラワーク、照明・スタイル、そして望ましい音声を明記してください。例は以下の通りです。
Scene: a single red fox in a snow-covered pine forest at dawn.
Action: the fox walks steadily left to right and looks toward the camera once.
Camera: medium-height lateral tracking shot, 50 mm lens, stable framing.
Look: photorealistic fur, cold blue ambient light, warm sunrise rim light.
Audio: soft footsteps in snow, light wind through pine branches, no music.
人物の同一性やオブジェクトの数などが重要となる場合は、それらを明示的に記載してください。--seed N でネイティブな乱数ストリームを制御します(デフォルトは 42)。同じプロンプト、シード値、解像度、フレーム数、ステップ数で比較オプションを確認しましょう。
7. フレームのプレビューとパフォーマンス診断
--showは、各ノイズ除去遷移後に代表フレームを表示し、完了した動画の全フレームを続けて表示します。Irisと同様に、Retinaディスプレイではデフォルトで2倍の表示サイズが適用されますが、--zoom Nを指定することでこの倍率を変更でき、画像のリサイズは行われません。
生成された動画、またはエンコードされたターミナル画像。
--frames-dir DIRオプションは、最終的なコールバックフレームを PPM 形式のファイルとして書き出します。ただし、中間段階で表示される--showプレビューはこのディレクトリには保存されません。
-o ''で MP4 エンコードを無効化します。FFmpeg が利用できない場合は、--frames-dirと併用してください。
--profileでは、フェーズの壁時間(wall time)、Metal によるエンコード/待機時間、ピーク時の生テンソルストレージ量、累積割り当て量、ディスパッチ回数が報告されます。
例:
./h3 --profile -d ./MiniMax-H3 -p "A hummingbird hovering over red flowers." \
--width 512 --height 512 --frames 22 --steps 20 \
--layers 45 --reuse 2 --frames-dir outputs/hummingbird-frames \
-o ''8. 画像・動画・音声の参照を追加する
最初フレームまたは最後フレームのアンカーは、FL2VA パスを選択します:
./h3 -d ./MiniMax-H3 -p "The fox keeps walking through the snow." \
--width 512 --height 512 --frames 22 --steps 20 \
--layers 45 --reuse 2 \
--first-frame fox.png --last-frame fox-later.png \
-o outputs/fox-anchored.mp4異なる Ref2VA チェックポイントを選択するには、メディアのセマンティクスに一致するフラグを指定してください。
# One image reference.
./h3 -d ./MiniMax-H3 -p "Use the animal and setting in the reference." \
--width 512 --height 512 --frames 22 --steps 20 \
--ref-image fox.png -o outputs/fox-reference.mp4
# Continue a clip but ignore its soundtrack.
./h3 -d ./MiniMax-H3 -p "Continue the motion in this clip." \
--width 512 --height 512 --frames 22 --steps 20 \
--ref-silent-video fox.mp4 -o outputs/fox-video-reference.mp4
# Preserve the clip's embedded audio.
./h3 -d ./MiniMax-H3 -p "Continue this audiovisual scene." \
--width 512 --height 512 --frames 56 --steps 20 \
--ref-video fox-with-audio.mp4 -o outputs/fox-video-audio.mp4
# Replace a video's soundtrack explicitly.
./h3 -d ./MiniMax-H3 -p "Continue the scene with the supplied music." \
--width 512 --height 512 --frames 56 --steps 20 \
--ref-video-audio silent-fox.mp4 replacement.wav \
-o outputs/fox-replaced-audio.mp4
# An ordered image plus standalone audio reference.
./h3 -d ./MiniMax-H3 -p "Use the animal and music from the references." \
--width 512 --height 512 --frames 56 --steps 20 \
--ref-image fox.png --ref-audio music.wav \
-o outputs/fox-image-audio.mp4参照フラグは複数回指定可能で、コマンドラインでの順序は保持されます。音声のみ単独で使用することはできず、必ず画像または動画の参照と併用する必要があります。音声参照の長さは 2〜15 秒とし、入力数は最大 3 つまで、合計のデコード済み再生時間は 15 秒以内で制限されています。
テストとランタイム要件
make test
make paritymake test コマンドは、決定論的なホストスイートを実行します。また、misc/fixtures/ ディレクトリに無視対象の MLX Fixture をインストールした場合、ランタイムで Metal ソースをコンパイルし、Toy H3 ブロックが MLX の名前付き出力と一致するかチェックします。このランタイムコンパイルは意図的な設計であり、Iris に倣ったものです。これにより、Xcode のオプションであるオフライン Metal ツールチェーンへの依存を排除しています。
テストでは、F32 形式の診断パスと、本番用の BF16 保存パスの両方をカバーします。広範な BF16 行列積や SDPA(Sparse Densely Packed Attention)については、キャッシュされた MPSGraph グラフを使用し、Metal の正確性に関するフォールバック処理も用意されています。
make parity コマンドは、Metal と MLX のチェックのみを実行します。
メディア入力と MP4 出力には、PATH に FFmpeg と FFprobe が存在している必要があります(H3_FFMPEG および H3_FFPROBE を使用すれば、特定の実行ファイルを明示的に指定できます)。生成された RGB24 と 32 kHz ステレオの F32 PCM は、並行したパイプを通じて転送され、中間の非圧縮メディアファイルは作成されません。
実装とパフォーマンスに関するノート
以下の記述では、チュートリアルプリセットの実装内容や、正確な A/B 診断のために維持されている環境変数について解説します。
サンプラーと DiT の制御
デフォルトのサンプラーは、公開されたシフト済みビデオ/オーディオスケジュールを使用します。--steps は常に拡散パスの回数を示し、最後のパスの後にターミナルゼロが追加されます。全体拡散器の再利用では、最初のパスと最後のパス、および指定された間隔の評価を行い、スキップされたビデオとオーディオの速度をそれぞれの独立したスケジュールに基づいて外挿します。ステップ数が非常に少ない場合は、--reuse 1 を維持してください。
低予算のパスでは、公開された線形ベースグリッドが、実際のビデオシグマ線形間隔、二次および三次歪み、正確な 30 ポイントの尾部サブセット、穏やかなパワー歪み、ゼロ次保持フルグリッド速度、線形速度外挿、そして RES を上回って勝利しました。
より尾部に重点を置いた候補は被写体をシャープにする一方で、動きを損ない、背景に繰り返される織り目模様を残すことがありました。スパースな RES や長い外挿間隔では、失敗がより顕著に現れました。
レイヤー薄化は、チェックポイントの実際の AdaLN ゲートを実行順序でランク付けしつつ、構造的に重要な最初のブロックと最後のブロックを保護します。使用されない重みやスケジューリングテンソルは保持されないので、--layers 45 や --layers 40 を指定すると、トランスフォーマーの処理時間と統一メモリの使用量の両方を削減できます。
コア再利用では、既存のフルトランスフォーマーの残差を保持したまま、パッチ射影と時刻認識ヘッドを更新します。これは「全体速度の再利用」とは排他的な関係にあります。
正確な DiT 融合
各アクティブな DiT ブロックは、アテンションの残差ゲートを次の MLP の AdaLN と融合させます。丸められた BF16 形式の残差値は正確に書き込まれますが、同じ行はスレッドグループメモリ内に保持され正規化が行われるため、ディスパッチとグローバルメモリの再読み込みをそれぞれ 1 回削減できます。トークン削減境界から離れた領域では、MLP の残差ゲートは次のブロックのアテンション AdaLN も生成し、その正規化された状態をループ全体で伝播させます。
H3_DISABLE_FUSED_GATE_ADALN=1 および H3_DISABLE_FUSED_CROSS_BLOCK_ADALN=1 を設定すると、これらは 2 つのカーネルによる従来の動作(オラクル)に復元されます。最終的なオーディオ/ビデオ用 AdaLN カーネルは、残差内のオフセットに直接バインドされます。
ストリーミング処理により、512x512 解像度で 2 つのスライス転送と 18.8 MiB の一時領域を回避できます(864 クラスのベンチマーク形状では 29.4 MiB)。
H3_DISABLE_FUSED_FINAL_SLICE=1 を設定すると、読み込み時にコピー+AdaLN オラクルが復元されます。BF16 の最終ヘッダは、16x16 の投影タイルを読み込む際に AdaLN を適用しますが、独立した丸めと累積順序は維持しつつ、同等サイズの正規化活性化を 1 つ削減します。この 2 つの最適化を組み合わせることで、37.5/58.9 MiB のメモリ節約が可能です。H3_DISABLE_FUSED_FINAL_HEAD=1 を設定すると、読み込み時にオフセット AdaLN+線形演算オラクルが復元されます。
トークン削減の内部仕組み
--token-reduction は、独立した積極的な DiT モードです。ブロック 3 を過ぎると、このモードは隣接する水平方向のターゲット動画トークンをペアリングしますが、テキスト、オーディオ、条件、参照トークンはそのまま正確に保持します。完全なフル解像度の状態はバイパスとして維持されます。最初の 10 回のノイズ評価ではブロック 40 の前に復元され、その後の詳細形成の評価ではブロック 30 の前に復元されます。各トークンは元の値に戻りつつ、ペアによって学習された更新分も加算されるため、ペア内の詳細情報が失われることはありません。
プーリングカーネルは、すでに割り当てられたアテンションスクラッチバッファの濃密な尾部に、真のペアベースラインのみを書き込みます。幅が奇数の単独トークンにはベースラインは不要です。完全バイパスでは、サイズが許す限り過剰な QKV 尾部を使用し、参照要素が多いレイアウトの場合のみ安全装置付きの専用フォールバックを用意します。そのため、テキストのみのキャンバスでは、あらゆるトークングリッド幅において追加の活性化領域を消費することはありません。プーリングはまた、ソーストークンの両方を BF16 値がすでにレジスタにある間にスナップショットするため、別途フルヒドンを転送する処理や冗長なソース読み込みを回避できます。
同じエントリーカーネルは、プールされた各行をスレッドグループメモリに保持し、最初の削減ブロックのアテンション AdaLN を出力します。これにより、別のグローバル残差読み込みが不要になります。復元境界では、最初のフル解像度アテンション AdaLN が展開処理に統合されます。10.5 KiB のスレッドグループ行は、続く残差ブランチが必要とする正確なバイパスを書き出しつつも、グローバル残差の再読み込みを回避します。
熱バランスが保たれた 512x512x22 の構成において、19 フォワードの IT M5 Max A/B でこの削減されたデノイズ
処理時間は 39.13 秒から 28.06 秒(28.3% の短縮)に短縮されました。最終的な動画・音声の潜在表現における相対 L2 ノルム誤差は、それぞれ 5.56%、15.14% です。
最初のフレーム、中間のフレーム、最後のフレームにおいて、キツネは滑らかな口元、整合性のある脚、鮮明な毛並みを維持しました。また、独立したサーファーも、波しぶきの中を一人のライダーとボードで一貫して描かれています。
この手法は構成を変更するものであり、デフォルトの厳密な参照ではなく、オプションとして選択可能な機能です。
H3_TOKEN_REDUCTION_BLOCKS は、後の 4:30 間隔を上書きできます。
H3_TOKEN_REDUCTION_EARLY=STEPS:END は、初期スケジュールを上書きし、0 に設定します。
これを無効化します。H3_DISABLE_TOKEN_REDUCTION=1 は、コンテキスト内の正確なオラクルを提供します。
H3_DISABLE_FUSED_TOKEN_POOL_ADALN=1 および
H3_DISABLE_FUSED_TOKEN_ADALN=1 を設定することで、診断用に 2 つのカーネルのエントリとエグジット境界を独立して復元できます。
トークン削減は、検証済みの --layers 45 --reuse 2 の設定と相性が良く、同じ 512 ベンチマークにおいてプロファイル値を 16.69 から
12.60 秒(マージナル値 24.5%)で、独立した狐とサーファーのレンダリングはどちらも一貫性を保ちました。ただし、--layers 40 と --reuse 3 を同時に組み合わせることは避けてください。その 6.47 秒の実験では潜在空間の正規性は許容範囲内でしたが、色環状の縞(クロマティック・リングイング)や手足が重なるゴースト現象が発生しました。
インターナルキャンバスと動画 VAE
--render-width と --render-height を指定すると、モデルと VAE はアスペクト比を維持した低解像度の内部キャンバス上で動作し、コールバックや端末表示、エンコードの前に高品質な vImage スケール処理で RGB フレームを要求された出力サイズに拡大します。これは明確な画質と速度のトレードオフです:384 から 512 へのプロンプトレンダリングでは、M5 DiT の実行時間が 33% 短縮され、video-VAE の処理時間も 18% 短縮されましたが、清潔で認識可能な写実的な結果は維持されています。両方の値は 32 の倍数である必要があり、出力キャンバスの正確なサイズはデフォルトのままです。
正方形の 512 出力において、384 は高速かつ高品質な設定ポイントであり、320 は検証済みの積極的な設定ポイントです。後者の設定では、歩行するキツネの一貫した生成に成功し、DiT の実行時間がネイティブ処理の約 15.82 秒に対して 8.02 秒となりました。ネイティブな 256 解像度は、前述のコストのかからない空間 RoPE 適応を同じコストで利用します。これはあくまで高速な構成プレビューであり、512 や 768 クラスの最終レンダリングを代替するものではありません。
動画 VAE は自動的に要求されたキャンバスの幾何形状から 256〜320 ピクセルの空間タイルを選択し、重複したオーバーラップ処理を最小化しながらピークメモリ使用量を抑制します。H3_VAE_TILE_PIXELS=256 を設定すると、参照診断用の元の保守的なタイル計画が復元されます。
Weight residency and streamed prompt encoding
M5 クラスの GPU では、永続的なトランスフォーマー重みは匿名の共有バッファへコピーされるのではなく、safetensor シャードから直接マッピングされます。これにより、37 GiB のモデルファイルがバックアップ可能かつ回収可能な状態を維持でき、トランスフォーマー全体の処理時間がわずかに短縮されます。一方、M3 では高速なコピー済みバッファ経路が使用されます。H3_ZERO_COPY_WEIGHTS=0 を設定すると、診断目的で M5 の選択が無効化されます。
ストリーミングされる Qwen テキストエンコーダーは、将来のレイヤー用の小さなリングを事前に確保します。
バッファを確保し、8 つの I/O ワーカーでデータを充填しながら、Metal は現在のレイヤーを実行します。デフォルトのリング深さは、M3 以前のハードウェアでは 2 レイヤー、M5 では 3 レイヤーです(ターゲットマシンは 128 GiB)。H3_QWEN_PREFETCH=0 を設定すると、単一層の同期参照パスが復元されます。値を 1〜8 にすることでワーカー数を指定でき、H3_QWEN_PREFETCH_DEPTH=1 から 6 の範囲でリング深さを上書きできます。
--ssd-streamingは、DiT(Diffusion Transformer)向けの別モードで、より積極的なレジデンシー制御を実現します。このモードでは、ブロックごとの正規化重みのみがメモリ上に残され、2つの完全な BF16 行列スロットを交互に使用しながら、背景プロセスがチェックポイントオフセット順に次のスロットを読み込みます。同時に、現在の Metal コマンドバッファも並列実行されます。
Darwin(macOS)のアンキャッシュ読み取りにより、ファイルシステムキャッシュに第2のコピーが保持されるのを防ぎます。また、最初のアクティブブロックは最終ブロック処理時に再度プリフェッチされるため、次の拡散ノイズ除去評価のためにキャッシュされたインタラクティブな DiT がすぐに利用可能になります。
測定結果では、内部 SSD から約 13〜14.6 GiB/s のスループットを達成しました。H3_PROFILE=1 を使用すると、総読み取りバイト数、読み取りスループット、GPU 処理中に隠れなかった読み込み待機時間の割合が報告されます。
Metal 4 と TensorOps パス
M5 GPU では、シーケンス長が 2,048 までの間、DiT の QKV およびアテンション出力投影に対してネイティブの BF16 Metal 4/TensorOps が自動的に使用されます。コンパクトな Morton スケジュールは、Q/K/V を直接ヘッド主座のアテンション入力へルーティングし、3 つの MPSGraph 入力の転置を回避します。また、この経路はポータブル版とバイト単位で完全に一致しています。これにより、反復された IT/US M5 Max 実行における 512x512 の 50 ブロック順方向計算全体が約 2% 高速化されます。
2,049 から 3,072 の行数(864x480 を含む)では、2 つの行オフセット Morton ディスパッチにより効率的なタイル幾何形状が維持され、バランスの取れた実行において順方向計算全体が約 2% 向上します。より大きなシーケンスについては引き続き MPSGraph が使用されます。
H3_NAX=0 を設定すると、TensorOps の使用が無効化され、A/B の正確な診断が可能になります。この切り替えはランタイムでガードされており、コンパイルが利用できない場合は変更のないポータブルライブラリへ自動的にフォールバックします。
H3_NAX=1 を設定すると、より広範なネイティブ BF16 線形パスが強制されます。これは完全な 50 ブロックの MLX フィクスチャを通過しますが、オプトイン(任意選択)のままです。形状に厳密なマイクロベンチマークでは 128 行タイルが有利ですが、現在の DiT 実行では MPSGraph のスケジューリングが優位です。これにより、ベンチマークの性能低下をデフォルトとせずとも、後日の量子化や融合カーネル向けに動作する NAX 統合を維持できます。
H3_NAX=mlp を指定すると、より専門的な Metal 4 パスが選択されます。ペアになった FC1 ゲート/アップの TensorOps タイルがスレッドグループメモリ内で SwiGLU を適用し、活性化された中間層(幅 14,336)のみを出力します。その後、FC2 も引き続き TensorOps に依存します。
H3_DISABLE_NAX_MLP=1 は、同じプロセス内での A/B テストのために、このように作成されたコンテキスト内で MPSGraph ベースの MLP を維持します。このパスが意図的にオプトインとなっているのは、スケジューリングが OS の GPU スack に依存するためです。macOS 26.5.2 M5 Max では、孤立した実重量 MLP 実行で 1.3〜2.0% の性能向上が見られましたが、完全な 50 ブロックの順方向伝播では約 1〜3% の低下を記録しました。一方、同じコンテキスト内での A/B テストにおいて、同様の macOS 26.5 M5 Max は 1.4% の向上を示しました。結果として得られた 50 ブロックの速度は互いに近く(動画で L2 ノルム比 1.9%、音声で 2.4%)、バイト単位では同一ではありませんでした。
Specialized projection kernels
狭い DiT オーディオ/ビデオ出力ヘッドは、解放された小規模な F32 重みを一度だけ BF16 に変換し、Iris から派生した 16x16 タイル化線形演算を BF16 アクティベーションに対して直接適用します。生産環境における 320 レンダリング幾何形状の測定では、孤立したペアヘッドの評価において M3 Max で 2.30 倍、M5 Max で 1.83 倍高速化され、相対的な L2 ノルムは 8.64e-4 です。絶対値における M5 の節約効果は、評価あたり約 0.6 ミリ秒となります。
ステップ 3: Full fox および surfer シーケンスは、F32 ヘッドレンダリングに対してそれぞれ 29.9 dB、38.4 dB の高い精度を維持しました。H3_DIT_F32_FINAL=1 を設定すると、参照用ヘッドと追加の活性化バッファが復元されます。
F32 の 96->5376 ビデオおよび 32->5376 オーディオのパッチ投影では、専用の 16x16 コーペラティブタイルを使用します。これにより F32 の重み・入力値・累積値を保持したまま、タイル結果を直接 BF16 に丸め込みます。
ペア化された生産形状の測定は、M3 で 1.77 倍、M5 で 1.62〜1.78 倍高速化され、生成された RGB ストリーム全体がスカラーパスとバイト単位で完全に一致します。最終キャストを融合させることで、M3 では 2835 行のタイル処理時間が 2.499 ms から 1.734 ms に、M5 では 1.555 ms から 1.186 ms に短縮され、512/864 クラスの幾何形状において F32 スクラッチ領域がそれぞれ 38.27 MiB / 59.66 MiB 削減されます。H3_DISABLE_FUSED_PATCH_CAST=1 を設定すると、タイル化された F32 出力と単独キャストが復元され、H3_SCALAR_PATCH=1 にするとスカラー診断パスが選択されます。
同じタイルは出力を直接パックされた隠れストリームにバインドするため、BF16 メディアのステージングバッファとその転送処理が不要になります。これによりさらに 19.13/29.83 MiB のメモリ節約となり、M3 では 2835 行の境界処理時間が 1.847 ms から 1.730 ms に短縮されます。
M5 上での実行時間は 1.184 ms に短縮されました。Contiguous T2VA はバイトオフセットを使用しますが、FL2VA/Ref2VA はコンパクトな宛先行マップを採用しているため、各モダリティは単一の大きなディスパッチとして維持されます。完全な 6 セグメント構成の Ref2VA M5 ABBA はバイト単位で同一性を保ちながら、測定された順方向ペアあたりの処理時間を 5.067 秒から 5.033 秒へと改善しました。H3_DISABLE_FUSED_PATCH_PACK=1 を設定すると、ステージングバッファとパッキングブリートが復元されます。
スケジューリングと活性化メモリ
DiT コアは 2 つの順序付けられた Metal コマンドバッファに分割されており、第 1 パートの GPU 実行と第 2 パートの CPU エンコーディングが並行して実行されます。熱バランスを考慮した ABBA ベンチマークでは、M5 シリーズで深さ 60% の分割(30/50、27/45、24/40)が採用され、約 0.5〜1.8% の性能向上が確認されました。一方、M3 シリーズでは検証済みの 30/50 のケースのみを自動的に分割し、これが 1.2% 高速化された結果となりました(24/40 は M3 で性能低下を示したため)。操作順序と生成されるバイト列に変更はありません。
H3_DIT_COMMAND_BLOCKS=0 を指定すると単一のコマンドバッファに戻ります。値 1〜50 を設定することで分割比率をオーバーライドし、さらに微調整が可能です。
DiT の活性化バッファも、ブロック内の実際のライフタイムに従って管理されます。QKV プロジェクション領域はまずアテンションヘッドに再利用され、その後正規化された MLP 入力の領域として使われます。一方、現在の出力用アテンション領域は、そのブランチが消費された後に MLP 出力の領域として転用されます。この手法により、512 クラス幾何形状では 61.25 MiB、864 クラス幾何形状では 99.63 MiB のメモリを削減できますが、ディスパッチや演算内容には一切変更がありません。
H3_DISABLE_DIT_ACTIVATION_ALIAS=1 を設定すると、診断用の別々のバッファに戻すことができます。
不変の DiT 重みとバイアスに対する MPSGraph テンソルデータラッパーは、対応するリジデントバッファと共に保持されます。これにより、各ブロックやノイズ除去評価のたびに同じバインディングメタデータを再構築する必要がなくなり、テンソルストレージのコピーも不要になります。測定された ABBA による性能向上は、M3 Max で 1.6%、M5 Max で 0.4〜1.1% です。
活性化ラッパーは一時的な扱いに留められています。これらを保持すると M5 シリーズで性能が低下したためです。出力結果はバイト単位で完全に同一であり、H3_DISABLE_GRAPH_DATA_CACHE=1 を設定することで全テンソルに対して一時的なラッパーに戻すことができます。
M3 またはそれ以前のハードウェアでは、各 DiT ブロック内の 4 つの MPSGraph セグメントが、共通の基盤となる Metal コマンドバッファに対して 1 つの MPSCommandBuffer ラッパーを再利用します。熱バランスを考慮した反復実行を測定した結果、M3 Max では 1.0〜1.6% の高速化が確認されましたが、M5 では速度差は認められず、新しいラッパーを保持する方針となっています。環境変数 H3_REUSE_MPS_COMMAND=0 または 1 を指定することで、自動選択を上書きできます。計算結果はバイト単位で完全に一致します。
M5 においては、サービング用のオイラー・サンプラーが、パケット化された F32 の潜在変数とキャッシュされた BF16 の速度を Metal バッファ内に保持し続けます。各選択された拡散器の更新処理は、次の処理エンコードが完了するまで待機して行われるため、MPSGraph におけるバックプレッシャーを回避できると同時に、中間的な潜在変数や速度の読み戻し、再パッキングがすべて不要になります。2 回のウォームアップを含む 8 回の実行による A/B テストでは、最終的な潜在変数はバイト単位で完全に一致したまま、0.1% と 0.3% のわずかな性能向上が観測されました。
このパスにより、動画潜在要素ごとに約 16 バイトのトランジエントホスト状態を節約できます(768p の形状では約 136 MB)。M3 およびそれ以前の GPU ではデフォルトで CPU サンプラーが保持されます。H3_CPU_SAMPLER=1 で M5 でもこれを復元でき、H3_GPU_SAMPLER=1 を指定すれば GPU 状態経路を明示的に選択できます。また、H3_GPU_SAMPLER_WINDOW=0 とすると、より低速な非制限エンコード事前診断モードが有効になります。
チェックポイントのレイアウトとメディアパイプライン
公開されたチェックポイントは、各アテンションヘッドごとに DiT の QKV 行をインターリーブした形式で保存されています。ネイティブ Metal は、このレイアウトを融合された QK 正規化/RoPE カーネルで直接消費するため、チェックポイントの転置や追加の RAM 使用を防ぎます。以前は正体不明の解釈がなされていましたが、これがノイズの多い診断出力の原因でした。
公開された生成パスでは、結合オーディオの潜在表現をストリーミングネイティブの BigVGAN または AudioVAE で復号化し、同期された H.264 ビデオと 32 kHz ステレオ AAC オーディオを出力します。生成された波形は、修正後の MLX オラクルと比較して相対 L2 ノルムが 6.94e-5 の精度で一致しています。
--first-frame および --last-frame パラメータ、およびそれらの組み合わせでは、公開されている視覚 VAE エンコーダ、Qwen3-VL 視覚塔(ビジョンタワー)、そして深層スタック型マルチモーダル表現モデルが使用されます。
条件拡張の確率を 0.999 に設定し、ネイティブ DiT の条件行を固定しました。最初の画像はターゲットキャンバスに引き伸ばされ、最後の画像はアスペクト比を維持して中央から切り抜く「aspect-cover」スケーリングが適用されます。これはリファレンス実装と整合させるためです。--ref-image オプションを使用すると、一意の Ref2VA トランスフォーマーが選択され、順序付きの <Picture N> が保持されます。
プレゼンテーションでは、公開された縦横比を保持するリファレンスカンバスを使用します。
--ref-silent-video オプション additionally には、制限付きの 24 fps デコーディング、視覚 VAE の因果的な ceil(T/4) 圧縮、2 フレーム Qwen サンプリング、タイムスタンプ付の処理が含まれます。
<Video N> プレゼンテーション。--ref-video は埋め込まれたサウンドトラックを保持し、--ref-video-audio VIDEO AUDIO は明示的な置換音声を供給します。
--ref-audio オプションは、順序付けられた独立したクリップを追加します。参照音声は 32 kHz ステレオの F32 データとしてデコードされ、ネイティブ AudioVAE の事後平均パスでエンコードされます。その後、0.999 のクリーンな潜在変数に 0.001 のシード付きノイズを混合し、音声条件のタイムステップ 1.0 に固定して、視覚参照と同じ回転時間軸上に幅 32 の行としてパッキングします。音声入力は 2〜15 秒で、最大 3 つまで対応しています。
承認された場合、総デコード時間は最大 15 秒に制限され、単独のオーディオ参照には画像またはビデオ参照との組み合わせが必要です。
ネイティブオーディオエンコーダーは、実際の 2 秒間のステレオ試験において、修正後の MLX オラクルと比較して相対 L2 ノルムが 3.59e-6 の精度で一致します。この補正は重要です。元の MLX リシェイプは左/右のサンプルをインターリーブする処理を行っていましたが、公式の PyTorch/SGLang パスは、ステレオチャンネルを損なうことなくバッチ次元に統合します。
128 GB の M5 Max 環境では、クリーンなエンドツーエンドの画像+オーディオおよび埋め込みビデオ+オーディオのレンダリングはそれぞれ 74.58 秒、76.99 秒で完了しました。いずれもピーク物理メモリ使用量は約 40.1 GB で、スワップは発生していません。
プロファイリングと診断パス
--profile オプションは、Metal ベースの各フェーズを個別にレポートします。具体的には、ウォールタイム、CPU 側のコマンドエンコーディング、コミットからフェンス待ちまでの完全な時間、ルートコマンドの GPU タイムスタンプ、ピーク時の生テンソルストレージ、累積割り当て量、ディスパッチ回数などが含まれます。この待機時間の測定は、コマンドの完全なターンアラウンド時間を指します。一方、ルート GPU のタイムスタンプだけでは MPSGraph によって内部でスケジューリングされた子バッファが含まれない場合があるため、その場合は適切にラベル付けされます。
DiT の高速パスでは、各 BF16 fc1 -> SwiGLU -> fc2 ブロックを 1 つのキャッシュ済みグラフとして評価し、個別のグラフ境界や永続的な中間テンソルの発生を防ぎます。数値診断のために参照操作の境界を保持したい場合は、H3_DISABLE_FUSED_MLP=1 を設定してください。
M5 Metal 4 の TensorOps ハードウェアに対応している場合、ネイティブの int8 MLP エンジンがデフォルトで採用されます。このエンジンでは活性化値を動的に量子化し、出力チャネルごとに重みスケールを使用します。また、敏感な FC2 入力に対しては、1,024 チャネルごとに 1 つのスケールを割り当てます。
選択された FC2 カーネルは、32 KiB のスレッドグループタイルを繰り返し外部メモリに書き出すのではなく、スケーリング済みの部分積をプライベートな協調フラグメント内に保持します。固定の 50 レイヤー、19 トランジション、解像度 512x512 のレンダリングテストでは、M5 Max 環境において BF16 MPS を使用した場合に 36.30 秒、int8 を使用した場合に 25.80 秒という結果でした。デコードされたフレームの開始部、中間部、最終部では、被写体や構図、動きはすべて同一に保たれていますが、エッジ部分や毛並みの細かいディテールには差異が生じる可能性があります。
現在の診断実装では、A/B 比較テストで明示的に要求されない限り、BF16 と int8 の両方の MLP 重みを同時に保持しません。通常の int8 ロード時には、量子化処理が完了した直後に各ブロックの BF16 FC1/FC2 バッファを解放するため、測定されたピークテンソルストレージは BF16 パスの 36.4 GiB から 25.9 GiB に削減されます。ただし、ランタイムでの重み量子化には起動時間の増加というトレードオフがあります。
最も高速な M5 パスでは、各 DiT の QKV 射影を量子化し、既存の Q/K 正規化と RoPE カーネルの実行前に、ヘッド優先のアテンションレイアウトで Q/K/V タイルを直接書き込みます。固定された 50 レイヤー、19 トランジションの 512x512 レンダリングにおいて、この手法により推論時間が 25.80 秒から 19.32 秒に短縮されました。サンプリングした開始・中間・最終フレームでは、雪の中を歩く狐の一貫性のある詳細な描写が維持されていますが、量子化されたアテンションでは構図や微細なディテールに変化が生じる可能性があります。
参照用として BF16 射影を使用する場合は --use-slower-bf16-qkv を指定してください。通常の int8 ロードでは、量子化後に冗長な BF16 の QKV 重みを解放します。
デフォルトの M5 パスでは、以下のアテンション出力投影も int8 で動作します。同モデル間のクロステストを実施すると、シーケンス長 512 および 864 の場合、完全な順伝播処理がさらに 4.5-5.5% 高速化されます。デコードされたフォックスのレンダリング結果はクリアで、int8-QKV のみを使用した場合とほぼ一致しました。ただし、熱的に負荷のかかるノイズ除去プロセスには 19.18 秒を要しています。この投影を BF16 で維持したい場合は、--use-slower-bf16-attention-output オプションを使用してください。
この int8 パスでは、SDPA は結果をネイティブの [head,row,dimension] 順序のまま保持します。専用の 256 スレッドカーネルが各 H3 ロウを直接集約し、投影行列の行優先 int8 バッファへ量子化します。これにより、出力バイトを変更せずに中間のフル幅 BF16 トランスポーズを不要にしています。温度制御されたクロス実行では、完全な 512 および 864 のフォワードパスが約 0.2〜1.2% 高速化されます。
明示的な BF16 行優先 SDPA 出力と通常の量子化器に戻すには、--use-slower-row-major-attention-output オプションを使用してください。
M5 パスでは、QKV と MLP の活性化の量子化も、直前のゲート付き AdaLN カーネルに統合されています。これにより、50 レイヤーの順方向計算で 99 個の個別の量子化器ディスパッチが不要になり、出力バイト数は維持したまま、クロス測定値(crossed measurements)を約 0.3〜0.6% 改善しています。
個別の量子化器を復元したい場合は、--use-slower-unfused-int8-inputs オプションを使用してください。
融合されたゲート付き AdaLN パスは、幅 5,376 の H3 行全体を BF16x4 ベクトルとして読み込み、int8x4 として書き出します。スレッドごとの RMS シーケンスを計算する前に丸められた値をローカルにステージングするため、還元ツリーとすべての出力バイトは変更されません。交差測定ではさらに約 0.1〜0.5% の削減が実現されます。
既存の --use-slower-unfused-int8-inputs オプションにより、移植可能なスカラー処理やスタンドアロンの量子化器フォールバックが維持されています。
Q/K の RMS 正規化と RoPE は、int8 QKV プロジェクションタイル内でも実行されます。融合されたエピローグはバイトレベルで同一であり、交差 M5 測定では 512 で順方向処理を 2.1〜3.2%、864 では 1.0〜1.8% 改善します。
個別の Q/K カーネルに戻すには --use-slower-unfused-qkv-rope を使用してください。
このエピローグでは、各ワークアイテムあたり4つの隣接するQ/K次元をBF16x4のロードとストアで処理します。要素ごとの演算とBF16の丸め順序は変更されませんが、交差した冷却状態の測定により、512と864の両方で完全なフォワードが約0.4〜1.0%改善されます。同じ--use-slower-unfused-qkv-ropeオプションを使用すると、スカラー単独パスが復元されます。
最大 2,048 行までの場合、正確な RMS ループでは BF16x4 のロードを実行した後に、4 つの明示的な順序付き FMAs(Fused Multiply-Add)を行います。これにより出力ビットがすべて保持され、512 クラスのフォワード計算がさらに 0.5〜0.6% 向上します。より大きな形状ではスカラーロードを維持しますが、これは両方の形式で性能が同程度になるためです。スカラーロードを強制するには --use-slower-scalar-qkv-rms を使用してください。
int8 アテンション出力投影では、128 行分の行スケールと列スケールを、協働フラグメント要素ごとに再読み込みするのではなく、1 KiB のスレッドグループメモリにキャッシュします。2,048 行を超える場合、融合された QKV カーネルでも同様の手法を採用し、その後その記憶領域を逆 RMS 値の再利用に転用します。より小さな QKV 形状では直接ロードを維持しますが、これも両方の形式で性能が拮抗するためです。
原文を表示
h3-metal
Native MiniMax-H3 inference for Apple Silicon. The project is being built as a
sequence of working vertical slices: deterministic host/model metadata first,
then portable Metal block parity, prompt encoding, prompt-to-video/audio, and
first/last-frame conditioning and then ordered references.
Prompt-to-video/audio, first/last-frame conditioning, and ordered Ref2VA
image/video/audio references work end to end. The current work is incremental
H3-specific Metal performance and memory optimization on M3 Max and M5 Max.
Tutorial
1. Build and inspect the model
The examples assume that the Hugging Face snapshot is in ./MiniMax-H3 and
that FFmpeg and FFprobe are available on PATH.
make -j8
mkdir -p outputs
./h3 --info -d ./MiniMax-H3--info checks the model layout and prints the selected Metal device without
mapping all weights or generating media. Run ./h3 --help for the complete CLI
reference.
Without -p, the same binary starts an Iris-style interactive session:
./h3 -d ./MiniMax-H3 --width 512 --height 512 --steps 6Type a prompt to generate a numbered video. The session keeps the exact BF16
prompt conditioning, prepared DiT, and video decoder in memory, so repeating a
prompt with another seed avoids loading and encoding them again. Useful commands
are !status, !seed random, !seconds 2, !show, !save output.mp4, and
!cache. Use !help for the full, short list.
First/last-frame conditioning is persistent in the session:
h3> !first opening.png
h3> !last ending.png
h3> The camera moves slowly around the subject.
Use !first clear or !last clear to remove an anchor. Generated videos are
written to the session directory printed at startup.
For a general Ref2VA conditioning image, use !ref-image PATH instead. Images
are appended in order and exposed to the model as <Picture 1>, <Picture 2>,
and so on; filenames have no meaning to the model.
h3> !ref-image person.png
h3> Make the person shown in Picture 1 wave to the camera.
!refs lists the current order, !ref-remove N removes one entry, and
!refs clear removes them all. Ref2VA references cannot be mixed with
!first/!last anchors.
2. Make a first fast video
Start with the validated balanced preset. It generates 22 frames at 24 fps
(about 0.92 seconds), displays the evolving middle-video frame after every
denoising transition in a supported graphical terminal, and prints phase
timings:
./h3 --profile \
-d ./MiniMax-H3 \
-p "A red fox walks through fresh snow in a pine forest. Medium tracking shot, natural winter light, realistic fur, soft footsteps and wind." \
--width 512 --height 512 \
--frames 22 --steps 20 \
--layers 45 --reuse 2 \
--show \
-o outputs/fox-fast.mp4This is deliberately not the most aggressive configuration:
- --steps 20 performs the default 20 denoising passes.
- --reuse 2 computes 11 fresh denoiser velocities instead of all 20 and
extrapolates the skipped transitions.
- --layers 45 runs 45 of the 50 transformer blocks, reducing both time and
unified-memory use.
- --show is optional. It supports Kitty/Ghostty and
iTerm2/WezTerm/Konsole graphical protocols. It loads a resident preview VAE,
displays one representative middle-video frame after every Euler transition,
and then displays all final frames. Display dimensions default to 2x so the
image has its intended logical size on macOS Retina screens; use --zoom 1
on a non-HiDPI display. This adds preview decode time and roughly 10 GiB of
temporary model residency; runs without --show are unchanged.
- --profile is optional and does not select a different generation path.
The first process invocation also pays model loading and filesystem-cache
costs. Compare performance using repeated runs, and alternate variants when
the machines are warming up because this workload is sensitive to thermal
throttling.
For a very short iteration, request four denoising passes directly:
./h3 --profile \
-d ./MiniMax-H3 \
-p "A red fox walks through fresh snow in a pine forest. Medium tracking shot, natural winter light, realistic fur." \
--width 512 --height 512 --frames 22 \
--steps 4 --layers 50 --reuse 1 \
--show \
-o outputs/fox-four-step.mp4--steps N always means exactly N denoising passes. Four through seven passes
use the same schedule that won the low-budget comparison; increasing from 4
to 7 progressively improves detail and motion. Keep --reuse 1 at such small
budgets so every requested pass runs the model. --show displays one preview
after each pass.
Several tail-heavy schedules were evaluated because most visible cleanup
happens late in a long run. They preserved too few early composition updates
and produced woven texture, weak motion, or clipped colors. The retained mode
uses the released linear base grid with one terminal point. On the 512-square,
22-frame fox test, the selected four-pass result had 0.556 full-video SSIM
against a 29-pass reference; an independent surfer test measured 0.547. The
four-pass denoise took about 3.5 seconds on M5 Max, versus 26.4 seconds for the
reference.
For a low-memory run, add --ssd-streaming:
./h3 --profile \
-d ./MiniMax-H3 \
-p "A red fox walks through fresh snow in a pine forest." \
--width 512 --height 512 --frames 22 --steps 20 \
--layers 50 --reuse 1 --ssd-streaming \
-o outputs/fox-ssd.mp4This uses the original BF16 checkpoint without conversion or quantization. It
keeps two DiT blocks in memory and reads the next block from SSD while the GPU
runs the current one. On M5 Max, tracked DiT storage fell from about 36.5 GiB to
2.0 GiB at 512 square and 2.1 GiB at 864x480. A warm 50-block forward measured
1.35 versus 2.49 seconds at 512 square (84% slower), and 2.14 versus 2.68
seconds at 864x480 (26% slower). These are comparisons against the same
full-residency BF16 path, and the results were byte-identical in both checks.
The 2.0--2.1 GiB figure is the DiT's tracked tensor storage, not total system
RAM. Prompt encoding and the two VAEs run in separate phases rather than adding
their full peaks to it; the OS, media buffers, and output resolution still need
headroom. --show keeps a preview VAE resident and adds roughly 10 GiB, so omit
it for the lowest-memory run.
SSD streaming is an explicit memory/speed tradeoff and is not the default. It
cannot be combined with --use-int8-row-fc2. In an interactive session, use
!ssd-streaming on.
3. Move toward reference quality
Change one control at a time when evaluating quality. First restore all layers,
then all denoiser evaluations, and finally raise the default 20-pass schedule
to the slower 50-pass reference:
./h3 --profile \
-d ./MiniMax-H3 \
-p "A red fox walks through fresh snow in a pine forest. Medium tracking shot, natural winter light, realistic fur, soft footsteps and wind." \
--width 512 --height 512 \
--frames 22 --steps 50 \
--layers 50 --reuse 1 \
-o outputs/fox-close.mp4The defaults are --steps 20 --layers 50 --reuse 1; keep --steps 50
explicit for this close path. It performs 50 complete 50-block denoiser
forwards and is much more expensive than the default, but is the right oracle
when a fast mode changes the subject, anatomy, motion, or composition.
Numerical pixel identity with MLX is not expected because the random-number and
execution engines differ; the depicted content and motion should agree.
4. Choose a speed/quality preset
These controls are independent unless noted otherwise:
| Control | Slow reference | Default | Aggressive | Main impact |
|---|---|---|---|---|
| Denoising passes | --steps 50 | --steps 20 | --steps 4..7 | The number always names actual denoising passes. |
| Whole denoiser reuse | --reuse 1 | --reuse 2 | --reuse 3 | At 20 steps: 20, 11, or 8 fresh DiT evaluations. |
| Active DiT blocks | --layers 50 | --layers 45 | --layers 40 | Fewer blocks reduce compute and resident transformer weights. |
| Core residual reuse | --core-reuse 1 | --core-reuse 4 | --core-reuse 6 | Refreshes patch/head work every step but runs the expensive core less often. |
| Token reduction | off | optional | --token-reduction | Pairs horizontal video tokens inside middle blocks; faster but may change composition. |
| Internal canvas | output size | 384x384 for 512 square output | 320x320 | Runs DiT/VAE smaller, then upscales with vImage. |
On M5, --use-int8-row-fc2 uses one activation scale per FC2 row and a single
full-width TensorOps product. It is optional because it is less numerically
conservative than grouped int8. It reduced complete denoiser forwards by about
2.6% in reciprocal tests. Matched four-step fox and surfer videos kept the same
subjects, setting, and motion (full-video SSIM 0.919 and 0.828). In the
interactive session, use !int8-row-fc2 on.
--reuse and --core-reuse are mutually exclusive. Layer thinning can be
combined with either one.
To make the first command faster while keeping its output resolution, add
token reduction:
./h3 --profile \
-d ./MiniMax-H3 \
-p "A surfer riding inside a sharp blue ocean wave, one rider and one white board, realistic spray." \
--width 512 --height 512 --frames 22 --steps 20 \
--layers 45 --reuse 2 --token-reduction \
-o outputs/surfer-fast.mp4At the validated 512 square shape, token reduction cut the 45 layers + reuse 2 denoise profile from 16.69 to 12.60 seconds on the IT M5 Max. Independent
fox and surfer renders stayed coherent, but composition can diverge more from
the close path.
For an aggressive preview, render internally at 320 square and upscale to the
requested 512 square output:
./h3 --profile \
-d ./MiniMax-H3 \
-p "A red fox walking through snow, realistic, tracking shot." \
--width 512 --height 512 \
--render-width 320 --render-height 320 \
--frames 22 --steps 20 --layers 40 --reuse 3 \
-o outputs/fox-aggressive.mp4This combination produced a clean, recognizable 22-frame fox in validation,
but loses fine detail and can change framing. Do not add --token-reduction
to both --layers 40 and --reuse 3: that tested combination produced color
ringing, outlines, and ghosted limbs.
As an alternative to whole-velocity reuse, this keeps the timestep-dependent
patch and output heads fresh at every transition:
./h3 --profile \
-d ./MiniMax-H3 \
-p "A surfer riding a blue ocean wave." \
--width 512 --height 512 --frames 22 --steps 20 \
--layers 45 --core-reuse 4 \
-o outputs/surfer-core-reuse.mp4Use --core-reuse 6 only as an aggressive preview. Values above 6 are not
exposed because validation lost subject fidelity.
5. Pick resolution and duration
Width and height must each be multiples of 32, at least 32, and their product
must not exceed 768 * 1344 pixels. Those are mechanical limits, not a promise
that every tiny canvas has good model quality. H3-Base is a 768p model.
| Canvas | Current guidance |
|---|---|
512x512 | Safest development size; repeatedly validated with multiple prompts. |
768x768 | Validated close-quality square output; substantially more expensive. |
1344x768, 768x1344 | Released 768p-class landscape/portrait limit. |
1024x768, 768x1024 | Valid 4:3 and 3:4 768p-class canvases. |
384x384 internal to 512x512 | Validated fast-quality scaling point. |
320x320 internal to 512x512 | Validated aggressive scaling point. |
256x256 | Native fast-preview canvas with automatic low-resolution RoPE adaptation. |
For a fast native 256-square preview:
./h3 -d ./MiniMax-H3 \
-p "A red fox walks through fresh snow in a pine forest." \
--width 256 --height 256 \
--frames 22 --steps 20 \
--layers 50 --reuse 1 \
-o outputs/fox-256.mp4At 256 square, H3 has only an 8x8 effective spatial-token grid, so it has less
room for fine detail and complex composition. H3 automatically halves spatial
RoPE coordinates at exactly 256 square. This removed repeating lattice
artifacts in long fox renders and stayed coherent on an independent portrait,
without adding tokens or runtime. Use --use-reference-rope to restore the
released/MLX coordinates for parity checks. Keep token reduction off at this
size. Native 128 square remains unsupported: its 4x4 token grid did not
recover a recognizable subject even with adjusted RoPE.
--render-width and --render-height must be set together, must have the same
aspect ratio as the output, and cannot exceed the output dimensions. The model
and VAE use the internal size; terminal frames and the encoded video retain the
requested output size.
H3 emits 24 fps and aligns frame requests upward to 5 + 17*n:
Use --seconds N for a duration-oriented request, or --frames N for direct
frame control; the two options are mutually exclusive. Fractional seconds are
accepted. Seconds are converted at 24 fps and then rounded upward to the next
legal H3 temporal shape, so --seconds 10 produces 243 frames (10.125 seconds).
| Frames | Approximate video duration |
|---|---|
| 22 | 0.917 seconds |
| 39 | 1.625 seconds |
| 56 | 2.333 seconds |
| 107 | 4.458 seconds |
| 243 | 10.125 seconds |
| 362 | 15.083 seconds |
Short clips are useful for development. The released workflow is intended for
roughly 4–15 second videos. A request such as --frames 23 is rounded up to 39
frames rather than producing an arbitrary temporal shape.
6. Improve the prompt
A short prompt works, but the released system expects a Context-IR-like
description. State the subject, action, setting, camera, lighting/style, and
desired sound. For example:
Scene: a single red fox in a snow-covered pine forest at dawn.
Action: the fox walks steadily left to right and looks toward the camera once.
Camera: medium-height lateral tracking shot, 50 mm lens, stable framing.
Look: photorealistic fur, cold blue ambient light, warm sunrise rim light.
Audio: soft footsteps in snow, light wind through pine branches, no music.
Keep identity and object counts explicit when they matter. --seed N controls
the native random stream; the default is 42. Compare options with the same
prompt, seed, resolution, frame count, and step count.
7. Preview frames and diagnose performance
- --show displays a representative frame after every denoising transition,
followed by all frames from the completed video. Like Iris, it advertises 2x
display dimensions by default for Retina terminals; --zoom N changes that
factor without resizing the generated video or the encoded terminal image.
- --frames-dir DIR writes final callback frames as PPM files. Intermediate
--show previews are not written there.
- -o '' disables MP4 encoding; combine it with --frames-dir when FFmpeg is
unavailable.
- --profile reports phase wall time, Metal encoding/wait time, peak live
tensor storage, cumulative allocation, and dispatch counts.
For example:
./h3 --profile -d ./MiniMax-H3 -p "A hummingbird hovering over red flowers." \
--width 512 --height 512 --frames 22 --steps 20 \
--layers 45 --reuse 2 --frames-dir outputs/hummingbird-frames \
-o ''8. Add image, video, and audio references
First/last-frame anchors select the FL2VA path:
./h3 -d ./MiniMax-H3 -p "The fox keeps walking through the snow." \
--width 512 --height 512 --frames 22 --steps 20 \
--layers 45 --reuse 2 \
--first-frame fox.png --last-frame fox-later.png \
-o outputs/fox-anchored.mp4Ordered references select the distinct Ref2VA checkpoint. Use the flag matching
the media semantics:
# One image reference.
./h3 -d ./MiniMax-H3 -p "Use the animal and setting in the reference." \
--width 512 --height 512 --frames 22 --steps 20 \
--ref-image fox.png -o outputs/fox-reference.mp4
# Continue a clip but ignore its soundtrack.
./h3 -d ./MiniMax-H3 -p "Continue the motion in this clip." \
--width 512 --height 512 --frames 22 --steps 20 \
--ref-silent-video fox.mp4 -o outputs/fox-video-reference.mp4
# Preserve the clip's embedded audio.
./h3 -d ./MiniMax-H3 -p "Continue this audiovisual scene." \
--width 512 --height 512 --frames 56 --steps 20 \
--ref-video fox-with-audio.mp4 -o outputs/fox-video-audio.mp4
# Replace a video's soundtrack explicitly.
./h3 -d ./MiniMax-H3 -p "Continue the scene with the supplied music." \
--width 512 --height 512 --frames 56 --steps 20 \
--ref-video-audio silent-fox.mp4 replacement.wav \
-o outputs/fox-replaced-audio.mp4
# An ordered image plus standalone audio reference.
./h3 -d ./MiniMax-H3 -p "Use the animal and music from the references." \
--width 512 --height 512 --frames 56 --steps 20 \
--ref-image fox.png --ref-audio music.wav \
-o outputs/fox-image-audio.mp4Reference flags may be repeated and their command-line order is preserved.
Standalone audio must accompany an image or video reference. Audio references
must be 2–15 seconds; at most three audio inputs are accepted and their total
decoded duration is capped at 15 seconds.
Tests and runtime requirements
make test
make paritymake test runs the deterministic host suite and, when the ignored MLX fixture
is installed under misc/fixtures/, compiles the Metal source at runtime and
checks a complete toy H3 block against named MLX outputs. Runtime compilation is
intentional: it follows Iris and does not require Xcode's optional offline Metal
toolchain. The test covers both an F32 diagnosis path and the production BF16
storage path; wide BF16 matrix products and SDPA use cached MPSGraph graphs, with
direct Metal correctness fallbacks. make parity runs only those Metal/MLX
checks.
FFmpeg and FFprobe must be available on PATH for media inputs and MP4 output
(H3_FFMPEG and H3_FFPROBE may select explicit executables). Generated RGB24 and
32 kHz stereo F32 PCM are fed through concurrent pipes; no intermediate
uncompressed media file is created.
Implementation and performance notes
The remainder documents the implementation behind the tutorial presets and the
environment variables retained for exact A/B diagnosis.
Sampler and DiT controls
The default sampler uses the released shifted video/audio schedule. --steps
always names the number of denoising passes, with terminal zero added after the
last pass. Whole-denoiser reuse evaluates the first and last pass plus every
requested interval, then extrapolates skipped video and audio velocities on
their independent schedules. With very small step counts, keep --reuse 1.
For the low-budget path, the released linear base grid won against
actual-video-sigma linear spacing,
quadratic and cubic warps, exact 30-point tail subsets, mild power warps,
zero-order held full-grid velocities, linear velocity extrapolation, and RES.
The more tail-heavy candidates often sharpened the subject but damaged motion
or left a repetitive woven background; sparse RES and long extrapolation
intervals failed much more visibly.
Layer thinning ranks the checkpoint's actual AdaLN gates while protecting
structurally important first and final blocks. Unused weights and schedule
tensors are not retained, so --layers 45 and --layers 40 reduce both
transformer time and unified-memory use. Core reuse holds the previous full
transformer residual while refreshing the patch projection and timestep-aware
head; it remains mutually exclusive with whole-velocity reuse.
Exact DiT fusions
Every active DiT block fuses its attention residual gate with the following MLP
AdaLN. The rounded BF16 residual is still written exactly, but the same row is
kept in threadgroup memory for normalization, eliminating one dispatch and one
global reread. Away from token-reduction boundaries, the MLP residual gate also
produces the next block's attention AdaLN and carries that normalized state
across the loop. H3_DISABLE_FUSED_GATE_ADALN=1 and
H3_DISABLE_FUSED_CROSS_BLOCK_ADALN=1 restore the two-kernel oracles.
The final audio/video AdaLN kernels bind directly to offsets in the residual
stream, avoiding two slice blits and 18.8 MiB of scratch at 512x512 (29.4 MiB
at the 864-class benchmark shape).
H3_DISABLE_FUSED_FINAL_SLICE=1 restores the copy-plus-AdaLN oracle at load.
The BF16 final heads then apply AdaLN while loading their 16x16 projection
tiles, preserving the standalone rounding and accumulation order while
removing another equally sized normalized activation. The two optimizations
together save 37.5/58.9 MiB. H3_DISABLE_FUSED_FINAL_HEAD=1 restores the
offset-AdaLN-plus-linear oracle at load.
Token-reduction internals
--token-reduction is an independent aggressive DiT mode. After block 3 it
pairs adjacent horizontal target-video tokens while leaving text, audio,
conditions, and reference tokens exact. The complete full-resolution state is
kept as a bypass. During the first ten noisy evaluations it restores before
block 40; subsequent detail-forming evaluations restore before block 30. Each
token returns as its original value plus the update learned by its pair, so
within-pair detail is not discarded.
The pooling kernel writes only true-pair baselines into a dense tail of the
already allocated attention scratch buffer; odd-width singleton tokens need no
baseline. The full bypass uses the oversized QKV tail when it fits, with a
guarded dedicated fallback only for reference-heavy layouts. Common text-only
canvases therefore add no activation arena at any token-grid width. Pooling
also snapshots both source tokens while their BF16 values are already in
registers, avoiding a separate full-hidden blit and redundant source read. The
same entry kernel keeps each pooled row in threadgroup memory and emits the
first reduced block's attention AdaLN, eliminating another global residual read.
At the restore boundary, the first full-resolution attention AdaLN is fused
into expansion: a 10.5 KiB threadgroup row avoids a global residual reread while
still writing the exact bypass needed by the following residual branch.
On a thermal-balanced 512x512x22, 19-forward IT M5 Max A/B this reduced denoise
time from 39.13 to 28.06 seconds (28.3%). Final video/audio latent relative L2
was 5.56%/15.14%. First/middle/last fox frames retained one clean muzzle,
coherent legs, and sharp fur; an independent surfer remained consistent with
one rider and board through the wave spray. It changes composition and is
therefore opt-in rather than the close-reference default.
H3_TOKEN_REDUCTION_BLOCKS can override the later 4:30 interval;
H3_TOKEN_REDUCTION_EARLY=STEPS:END overrides the early schedule and 0
disables it. H3_DISABLE_TOKEN_REDUCTION=1 provides an in-context exact oracle.
H3_DISABLE_FUSED_TOKEN_POOL_ADALN=1 and
H3_DISABLE_FUSED_TOKEN_ADALN=1 independently restore the two-kernel entry and
exit boundaries for diagnosis.
Token reduction composes cleanly with the validated --layers 45 --reuse 2
settings: on the same 512 benchmark it reduced that profile from 16.69 to
12.60 seconds (24.5% marginal), and independent fox and surfer renders stayed
coherent. Do not combine it with both --layers 40 and --reuse 3; that
6.47-second experiment produced chromatic ringing and ghosted limbs despite
acceptable latent norms.
Internal canvas and video VAE
--render-width and --render-height run the model and VAE on a lower
same-aspect internal canvas, then high-quality vImage-scale RGB frames to the
requested output size before callbacks, terminal display, and encoding. This is an
explicit quality/speed tradeoff: a measured 384-to-512 prompt render reduced
M5 DiT time by 33% and video-VAE time by 18% while retaining a clean,
recognizable photorealistic result. Both values must be multiples of 32; the
exact output canvas remains the default.
For square 512 output, 384 is the fast-quality point and 320 is the validated
aggressive point. The latter produced a coherent walking fox and repeated at
8.02 seconds of DiT versus about 15.82 seconds natively. Native 256 uses the
same-cost spatial-RoPE adaptation described above; it remains a fast composition
preview rather than a substitute for a 512- or 768-class final render.
The video VAE automatically chooses a 256-320 pixel spatial tile from the
requested canvas geometry, minimizing repeated overlap work while keeping peak
storage bounded. H3_VAE_TILE_PIXELS=256 restores the original conservative
tile plan for close-reference diagnosis.
Weight residency and streamed prompt encoding
On M5-class GPUs, persistent transformer weights are mapped directly from their
safetensor shards instead of copied into anonymous shared buffers. This keeps
the 37 GiB model file-backed/reclaimable and slightly improves total transformer
time; M3 uses the faster copied-buffer path. H3_ZERO_COPY_WEIGHTS=0 disables
the M5 selection for diagnostics.
The streamed Qwen text encoder preallocates a small ring of future layer
buffers and fills them on eight I/O workers while Metal executes the current
layer. The default ring depth is two layers on M3/older hardware and three on
M5, where the target machine has 128 GiB. H3_QWEN_PREFETCH=0 restores the
single-layer synchronous reference path; values 1-8 select the worker count,
and H3_QWEN_PREFETCH_DEPTH=1 through 6 overrides the ring depth.
--ssd-streaming is a separate, more aggressive residency mode for the DiT.
Only its small per-block normalization weights remain resident. Two complete
BF16 matrix slots alternate while a background reader fills the next slot in
checkpoint-offset order; the current Metal command buffer runs concurrently.
Darwin uncached reads avoid retaining a second copy in the filesystem cache.
The first active block is prefetched again during the final block, so a cached
interactive DiT is ready for its next denoiser evaluation. Measurements reached
about 13--14.6 GiB/s from the internal SSD. H3_PROFILE=1 reports total bytes,
read throughput, and the part of the read wait that was not hidden by GPU work.
Metal 4 and TensorOps paths
M5 GPUs automatically use native BF16 Metal 4/TensorOps for the DiT QKV and
attention-output projections at sequence lengths up to 2,048. The compact
Morton schedule routes Q/K/V directly into head-major attention inputs, avoids
three MPSGraph input transposes, and is byte-identical to the portable path. It
improves a complete 512x512 50-block forward by about 2% across repeated IT/US
M5 Max runs. For 2,049-3,072 rows, including 864x480, two row-offset Morton
dispatches preserve the efficient tile geometry and improve the complete
forward by about 2% in balanced runs. Still larger sequences stay on MPSGraph.
H3_NAX=0 disables TensorOps for exact A/B diagnosis. The selection is guarded
at runtime and falls back to the unchanged portable library if compilation is
unavailable.
H3_NAX=1 forces the broader native BF16 linear path. It passes the complete
50-block MLX fixture, but remains opt-in: exact-shape microbenchmarks favor its
128-row tile while full DiT runs currently favor MPSGraph scheduling. This
keeps a working NAX integration available for later quantized/fused kernels
without making a benchmark regression the default.
H3_NAX=mlp selects a more specialized Metal 4 path: paired FC1 gate/up
TensorOps tiles apply SwiGLU in threadgroup memory and write only the
14,336-wide activated intermediate, then FC2 also stays on TensorOps.
H3_DISABLE_NAX_MLP=1 keeps the MPSGraph MLP in a context created this way for
same-process A/B testing. The path is deliberately opt-in because scheduling
depends on the OS GPU stack: the primary macOS 26.5.2 M5 Max gained 1.3-2.0%
in isolated real-weight MLP runs but lost about 1-3% in a complete 50-block forward,
while an otherwise identical macOS 26.5 M5 Max gained 1.4% in a same-context
forward A/B. The resulting 50-block velocities were close (1.9% video and 2.4%
audio relative L2), but not byte-identical.
Specialized projection kernels
The narrow DiT audio/video output heads convert their small released F32
weights to BF16 once and use the Iris-derived 16x16 tiled linear directly on
BF16 activations. At the production 320-render geometry, isolated paired-head
measurements are 2.30x faster on M3 Max and 1.83x faster on M5 Max, with
relative L2 8.64e-4; the absolute M5 saving is about 0.6 ms per evaluated
step. Full fox and surfer sequences remained clean and measured 29.9/38.4 dB
against the F32-head renders. H3_DIT_F32_FINAL=1 restores the close-reference
head and its extra activation buffers.
The F32 96->5376 video and 32->5376 audio patch projections use a dedicated
16x16 cooperative tile, retaining F32 weights, inputs and accumulation while
rounding the tile result directly to BF16.
Paired production-shape measurements are 1.77x faster on M3 and 1.62-1.78x
on M5; the complete generated RGB stream is byte-identical to the scalar path.
Fusing the final cast improves the 2835-row tile itself from 2.499 to 1.734 ms
on M3 and 1.555 to 1.186 ms on M5, and removes 38.27/59.66 MiB of F32 scratch
at 512/864-class geometry. H3_DISABLE_FUSED_PATCH_CAST=1 restores the tiled
F32 output plus standalone cast; H3_SCALAR_PATCH=1 selects the scalar
diagnostic path.
The same tile binds its output directly into the packed hidden stream, removing
the BF16 media staging buffers and their blits. This saves another 19.13/29.83
MiB and improves the 2835-row boundary from 1.847 to 1.730 ms on M3 and 1.282
to 1.184 ms on M5. Contiguous T2VA uses byte offsets; FL2VA/Ref2VA use compact
destination-row maps so each modality remains one large dispatch. A complete
six-segment Ref2VA M5 ABBA remained byte-identical and improved 5.067 to 5.033
seconds per measured forward pair. H3_DISABLE_FUSED_PATCH_PACK=1 restores the
staging buffers and packing blits.
Scheduling and activation memory
The DiT core is split into two ordered Metal command buffers so GPU execution
of the first part overlaps CPU encoding of the second. Thermal-balanced ABBA
measurements select a 60%-depth split on M5 (30/50, 27/45, and 24/40), with
roughly 0.5-1.8% wins; M3 automatically splits only the validated 30/50 case,
which measured 1.2% faster, because 24/40 regressed there. The operation order
and generated bytes are unchanged. H3_DIT_COMMAND_BLOCKS=0 restores one
command buffer; values 1-50 override the split for further tuning.
DiT activation buffers also follow their actual intra-block lifetimes: the QKV
projection arena is reused first for attention heads and then for the normalized
MLP input, while the current attention-output arena becomes the MLP output after
its branch has been consumed. This removes 61.25 MiB at 512-class geometry and
99.63 MiB at 864-class geometry without changing dispatches or arithmetic.
H3_DISABLE_DIT_ACTIVATION_ALIAS=1 restores separate diagnostic buffers.
MPSGraph tensor-data wrappers for immutable DiT weights and biases are retained
with their resident buffers. This avoids rebuilding the same binding metadata
for every block and denoiser evaluation without copying tensor storage; measured
ABBA gains were 1.6% on M3 Max and 0.4-1.1% on M5 Max. Activation wrappers stay
transient because retaining them regressed the M5. The outputs remain
byte-identical, and H3_DISABLE_GRAPH_DATA_CACHE=1 restores transient wrappers
for all tensors.
On M3/older hardware, the four MPSGraph segments in each DiT block also reuse
one MPSCommandBuffer wrapper for their shared underlying Metal command buffer.
Repeated thermal-balanced runs measured 1.0-1.6% faster on M3 Max; M5 measured
neutral, so it retains fresh wrappers. H3_REUSE_MPS_COMMAND=0 or 1 overrides
the automatic selection. Results are byte-identical.
On M5, the serving Euler sampler keeps its patch-packed F32 latents and cached
BF16 velocities in Metal buffers. Each selected denoiser refresh is completed
before the next is encoded, avoiding MPSGraph back-pressure while removing all
intermediate latent/velocity readbacks and repacking. Two warm eight-run A/B
sequences measured small 0.1% and 0.3% gains with byte-identical final latents;
the path also saves roughly 16 bytes of transient host state per video-latent
element (about 136 MB at the 768p shape). M3 and older GPUs retain the CPU
sampler by default. H3_CPU_SAMPLER=1 restores it on M5;
H3_GPU_SAMPLER=1 selects the GPU-state path explicitly, and
H3_GPU_SAMPLER_WINDOW=0 enables the slower unbounded encode-ahead diagnostic.
Checkpoint layout and media pipeline
The released checkpoint stores DiT QKV rows interleaved per attention head.
Native Metal consumes that layout directly in the fused QK-normalization/RoPE
kernel, avoiding a checkpoint transpose and extra RAM. The earlier identity
interpretation was the cause of the noisy diagnostic outputs.
The public generation path decodes the joint audio latent with a streamed native
BigVGAN/AudioVAE and writes synchronized H.264 plus 32 kHz stereo AAC. The native
waveform agrees with the corrected MLX oracle to relative L2 6.94e-5.
--first-frame, --last-frame, and their combination use the released visual
VAE encoder, Qwen3-VL vision tower and three-deepstack multimodal presentation,
0.999 condition augmentation, and fixed condition rows in the native DiT. The
first image is stretched to the target canvas; the last image is aspect-cover
scaled and center cropped, matching the reference implementation. --ref-image
selects the distinct Ref2VA transformer, preserves ordered <Picture N>
presentation, and uses the released down-only aspect-preserving reference canvas.
--ref-silent-video additionally performs bounded 24 fps decoding, the visual
VAE's causal ceil(T/4) compression, two-frame Qwen sampling, and timestamped
<Video N> presentation. --ref-video preserves an embedded soundtrack,
--ref-video-audio VIDEO AUDIO supplies an explicit replacement, and
--ref-audio appends an ordered standalone clip. Reference audio is decoded as
32 kHz stereo F32, encoded by the native AudioVAE posterior-mean path, mixed as
0.999 clean latent plus 0.001 seeded noise, pinned to the audio condition
timestep 1.0, and packed as width-32 rows on the same rotary timeline as visual
references. Audio inputs are 2-15 seconds, at most three are
accepted, their total decoded duration is capped at 15 seconds, and a standalone
audio reference must be combined with an image or video reference.
The native audio encoder matches the corrected MLX oracle at relative L2
3.59e-6 on a real two-second stereo fixture. The correction is important: the
original MLX reshape interleaved left/right samples, whereas the official
PyTorch/SGLang path folds intact stereo channels into the batch dimension. On
the 128 GB M5 Max, clean end-to-end image+audio and embedded-video+audio renders
completed in 74.58 and 76.99 seconds respectively, each with about a 40.1 GB
peak physical footprint and zero swaps.
Profiling and diagnostic paths
--profile reports each Metal-backed phase separately: wall time, CPU-side
command encoding, complete commit-to-fence wait, root-command GPU timestamps,
peak live tensor storage, cumulative allocation, and dispatch counts. The wait
measurement is the complete command turnaround; the root GPU timestamp alone
can omit child buffers scheduled internally by MPSGraph and is labeled
accordingly.
The DiT fast path evaluates each BF16 fc1 -> SwiGLU -> fc2 block as one cached
graph, avoiding separate graph boundaries and persistent intermediate tensors.
Set H3_DISABLE_FUSED_MLP=1 to retain the close-reference operation boundaries
for numerical diagnosis.
On supported M5 Metal 4 TensorOps hardware, the native int8 MLP engine is the
default. It dynamically quantizes activations, uses per-output-channel weight
scales, and gives the sensitive FC2 input one scale per 1,024 channels.
The selected FC2 kernel keeps scaled partial products in private cooperative
fragments instead of repeatedly spilling a 32 KiB threadgroup tile. A fixed
50-layer, 19-transition 512x512 render measured 36.30 seconds with BF16 MPS and
25.80 seconds with int8 on M5 Max. Beginning, middle, and final decoded frames
retained the same subject, composition, and motion; small edge and fur details
can differ. The current diagnostic implementation retains both BF16 and int8
MLP weights only when an A/B diagnostic requests them. Normal int8 loading
releases each block's BF16 FC1/FC2 buffers after their submitted quantization
finishes, reducing measured peak tensor storage to 25.9 GiB from the BF16
path's 36.4 GiB. Runtime weight quantization still adds startup time.
The fastest M5 path also quantizes each DiT QKV projection and writes its
Q/K/V tiles directly in head-major attention layout before the existing Q/K
normalization and RoPE kernel. In a fixed 50-layer, 19-transition 512x512
render this reduced denoising again, from 25.80 to 19.32 seconds. Sampled
beginning, middle, and final frames remained a coherent detailed fox walking
through snow; quantized attention can change framing and fine detail. Use
--use-slower-bf16-qkv for the close-reference BF16 projection. Normal int8
loading releases the redundant BF16 QKV weights after quantization.
The following attention-output projection is int8 as well on the default M5
path. Crossed same-model tests improve a complete forward by another 4.5-5.5%
at 512 and 864. A decoded fox render remained clean and closely matched the
int8-QKV-only composition; its thermally hot denoise measured 19.18 seconds.
Use --use-slower-bf16-attention-output to retain that projection in BF16.
On that int8 path, SDPA now leaves its result in native
[head,row,dimension] order. A specialized 256-thread kernel gathers and
quantizes each H3 row directly into the projection's row-major int8 buffer,
eliminating the intervening full-width BF16 transpose without changing any
output byte. Thermally controlled crossed runs improve complete 512 and 864
forwards by roughly 0.2-1.2%. Use
--use-slower-row-major-attention-output to restore the explicit BF16
row-major SDPA output and ordinary quantizer.
The M5 path also folds QKV and MLP activation quantization into the preceding
gated AdaLN kernel. This removes 99 standalone quantizer dispatches per
50-layer forward while preserving the previous output bytes, improving crossed
512/864 measurements by about 0.3-0.6%. Use
--use-slower-unfused-int8-inputs to restore the standalone quantizers.
The fused gated-AdaLN path loads its full 5,376-wide H3 rows as BF16x4 vectors
and writes int8x4. It stages the rounded values locally before computing the
original per-thread RMS sequence, so the reduction tree and every output byte
remain unchanged. Crossed measurements save roughly another 0.1-0.5%. The
existing --use-slower-unfused-int8-inputs option retains the portable scalar
and standalone-quantizer fallback.
Q/K RMS normalization and RoPE are performed inside the int8 QKV projection
tile as well. The fused epilogue is byte-identical and improves complete
forwards by 2.1-3.2% at 512 and 1.0-1.8% at 864 in crossed M5 measurements.
Use --use-slower-unfused-qkv-rope to restore the separate Q/K kernel.
That epilogue processes four adjacent Q/K dimensions per work item with
BF16x4 loads and stores. The per-element arithmetic and BF16 rounding order are
unchanged, while crossed cool-state measurements improve complete forwards by
about 0.4-1.0% at both 512 and 864. The same
--use-slower-unfused-qkv-rope option restores the scalar standalone path.
At up to 2,048 rows, the exact RMS loop uses BF16x4 loads followed by four
explicit ordered FMAs. This preserves every output bit and improves 512-class
forwards by another 0.5-0.6%; larger shapes retain scalar loads because the two
forms tie there. Use --use-slower-scalar-qkv-rms to force scalar loads.
The int8 attention-output projection caches its 128 row and column scales in
1 KiB of threadgroup memory instead of rereading them for every cooperative
fragment element. Above 2,048 rows the fused QKV kernel uses the same idea and
then recycles that storage for inverse RMS values; smaller QKV shapes retain
direct loads because the two forms tie
関連記事
今日のまとめ
AIデイリーブリーフで今日の重要ニュースをまとめ読み