コンテンツへスキップ
Week 0 NVIDIA DGX Spark 実験レポート

Week 0 NVIDIA DGX Spark 実験レポート

← 全記事

ある日、出社すると Harper(私たちの CEO)から「この NVIDIA Spark ボックスで何ができる?」と聞かれました。当時はまだリリース前だったので、正直なんのことか全く分かりませんでした。でも少し調べてみると、コンパクトなボディに 128GB の統合メモリを詰め込んだパッケージはなかなか面白いものだと気づきました。

It is very very gold and shiny
It is very very gold and shiny

データサイエンティストとしてここ十年ほどはニューラルネットワークの学習に多くの時間を費やしてきましたが、その最大の制約のひとつが GPU RAM でした。古い 1070/1080 カードから自前の 4090、業務用の A10 や H100 まで様々使ってきました。一般的な作業なら H100 でも十分こなせますが、128GB という容量をこのサイズの筐体で社内に持てるのはかなり新鮮です。Spark ボックスがどこまでやれるか確かめるために、いくつかのテストを実施することにしました。1. Ollama 経由で Llama 4 モデルをテキスト生成タスクに使い、128GB RAM を積んだ私の M4 Apple Silicon Mac と速度比較する。2. 新しい DeepSeek OCR モデル を動かせるよう設定する。3. Llama 3.1 70B モデルへの LoRA アダプターを学習させる。生成という基本的なパイプラインから、互換性トラブルシューティングが伴う新モデルの導入、そしてこれまでは自分では到底学習させられなかった規模のモデルを使ったトレーニングランまで、バランスよくカバーできるテスト内容だと思いました。## 「Hello World」— NVIDIA Spark で Llama 4 を動かす 接続環境を整えてシステムに慣れてきたころ、Meta の Llama 4 モデル を引っ張ってきて基本的なテキスト生成を試してみることにしました。Ollama と OpenWebGUI のインストールと起動はかなりスムーズで、パイプラインが十分文書化されていたおかげで所要時間は約 60 分ほど。そのほとんどは自分のミスで Llama 4 モデルを何度もダウンロードし直した時間です。選んだのは Llama 4 Scout モデルで、109B パラメータのうち任意の時点でアクティブになるのは 17B パラメータのサブセットです。モデルをダウンロードして実行したところ、予想どおり約 67GB のメモリを使用していました。NVIDIA のダッシュボード上ではメモリが全量割り当てられているように見えましたが、他の診断ツールで確認すると実際は想定どおりの 67GB 程度でした。

Nvidia DGX Spark memory usage dashboard
Nvidia DGX Spark memory usage dashboard

テキストを生成できるようになると、次に気になったのは生成速度でした。「まあ普通かな……でもそもそもどのくらい速いのか全く分からないな」という感じです。

Unsurprisingly it wasn't aware of the new DGX spark which makes perfect sense
Unsurprisingly it wasn’t aware of the new DGX spark which makes perfect sense

NVIDIA Spark vs M4 Apple Silicon 128GB DGX Spark ボックスは 10 月 15 日にリリースされ、

現在 10 月 24 日なので、今後もソフトウェアやドライバーのリリースが続いてメトリクスが改善し、トークン生成速度も上がっていくと予想されます。ただ Week 1 の時点でのベースラインとして数値をまとめました。今年の初めにチームで M4 Macbook Pro(128GB 統合メモリ)を購入しており、今回の比較に非常に好都合でした。Macbook を手に入れたとき、最初にやったことのひとつが大きなモデルをダウンロードして動かしてみることでした。約 1TB ほどモデルをダウンロードした後、最近の仕事はモデルのテストが中心ではなかったので、しばらくそういう作業はしていませんでした。Ollama 経由で Llama 4 モデルに 5 つのプロンプトを流してみた最初の印象は「M4 Mac のほうが圧倒的に速い」というものでした。短めのプロンプトと出力でテストした初期段階では、M4 が安定して 30+ tokens/s(秒あたりのトークン数)を出していたのに対し、DGX Spark は約 16.8 tokens/s でした。数字だけ見れば M4 Apple Silicon アーキテクチャの圧勝です。しかし面白いことに、コンテキスト長が増えると M4 のトークン生成速度は(予想どおり)低下した一方で、NVIDIA はほぼ一定の 16.8 tokens/s を維持していました。そこでさらにテストを追加し、ポケモン赤・青・黄のウィキペディアページ全文をコンテキストとして渡して長いテキストを生成させました。このウィキペディアページは約 6,000 語ほどで、ゲームについてのエッセイを生成させたところ、M4 は 18.81 tokens/s(38% 低下)、DGX Spark は 16.0 tokens/s(5% 低下)という結果になりました。M4 はまだわずかに速いですが、DGX Spark は予想していたような速度劣化をほとんど示しませんでした。### まとめ 10 月 24 日時点では、NVIDIA DGX Spark の Llama 4 モデルによる生成速度は、両機とも 128GB の統合 RAM を持つ条件で Apple Silicon M4 の約 79.6% です。ただし DGX Spark はコンテキスト長が増えても標準的な速度劣化を示しません。まだ初期段階なので最適化が進めば速度は上がるでしょうし、それが同様の劣化を引き起こさないなら DGX Spark は非常に魅力的になりえます。一方で、適切なカーネルやソフトウェアが Spark エコシステムに加わった際には、生成速度は速くなるが入出力シーケンスが長くなるにつれて低下するという、より一般的なパターンに収束していくのではないかと予想しています。成熟した段階では M4 の数値に近づくはずです。他の ブログ を読んでいると、DGX Spark の ARM64 アーキテクチャは Jetson ボードなど他のデバイスでの実績があって成熟している一方、Blackwell GB10 GPU は新しく CUDA 13.0 もリリースされたばかりだという指摘がありました。つまり、より充実したエコシステムに追いつくにはもう少し時間がかかるということです。Blackwell GB10 GPU のエコシステムが育ってくれば、トークン生成速度も上がり、長い入出力コンテキストでの通常の性能劣化も見られるようになるでしょう。価格面では、NVIDIA Spark ボックスはなかなか競争力があります。私たちがノートパソコンを購入したときの価格は $4,849 で、Spark は $4,000 です。用途によっては、今のところ他の選択肢より若干遅いとはいえ、128GB の統合メモリをより安価に使えます。エコシステムがもう少し整ってくれば、絶対的な応答速度を必要としない用途でのモデルテストやホスティング、あるいは 128GB メモリを活かした複数の小規模モデルのホスティングに、NVIDIA Spark は有力な選択肢になりえると思います。## DeepSeek OCR

I'm doing my first play through of Hollow Knight Silksong
I’m doing my first play through of Hollow Knight Silksong

このセクションは Simon Willison のブログ記事に触発されたものです。DeepSeek モデルは 3B パラメータのモデルで、以前にいくつかテストを済ませていたため環境には CUDA 13 が適切にセットアップされていました。Docker のセットアップは NVIDIA が PyTorch チュートリアル用に公開しているこちらの構成を大きく参考にしました。中心となるのは Docker コンテナ nvcr.io/NVIDIA/pytorch:25.09-py3 で、そこから Dockerfile(付録参照)を使って必要な設定を行います。### Claude Code での問題 最初は、このパイプラインで動作する transformers と Pytorch のバージョンを見つけるのに苦労しました。Pytorch 2.7 + CUDA 13 を試しましたが ARM64 と CUDA の両方に対応するバージョンが見つからず、Pytorch 2.9 + CUDA 13 に切り替えました。次に transformers のバージョン問題が発生し、LlamaFlashAttention2 のインポートエラーが出ました。最初に試したバージョンより古い transformers に戻すことで解決し、transformers==4.46.3 に固定することで起動周りの問題はひとまず解消されました。その後、振り返ってみると Simon も同じ問題に遭遇していた件に直面しました。保存された出力ファイルが最初は空白しか含まれていなかった問題です。Claude は「モデルを実行しました」と宣言しましたが、ファイルの中身を確認するよう伝えると混乱して「モデルが何も検出していない」と判断してしまいました。Silksong の壁紙にはテキストが確かにあると指摘すると、あとは正しいデータ構造を見つけるだけでした。ファイルへの書き出しではなく内容をそのままプリントしていただけだったのです。壁紙から検出されたテキストと座標は以下のとおりです。そこまで複雑なテストではありませんが、各セクションを正しく抽出し、適切なバウンディングボックス領域に分離し、ちょっと変わったテキストスタイルにも対応しています。

<|ref|>NINTENDO<|/ref|><|det|>[[160, 144, 240, 164]]<|/det|>
<|ref|>SWITCH.<|/ref|><|det|>[[24, 164, 115, 195]]<|/det|>
<|ref|>SWITCH.<|/ref|><|det|>[[160, 164, 240, 195]]<|/det|> <|ref|>HOLLOW
KNIGHT<|/ref|><|det|>[[384, 710, 600, 754]]<|/det|>
<|ref|>SILKSONG<|/ref|><|det|>[[299, 757, 699, 949]]<|/det|> ``` ### DeepSeek
OCR まとめ このプロセスは非常にスムーズで、所要時間は約 40〜60 分でした。このシステム上で動作することが分かっている Docker コンテナを土台にしたことで、作業が楽になり再現性も高まりました。詰まった点は新しいモデルを使う際によくある類いのもの——適切な Pytorch と transformers のバージョンの特定と、モデルのデータ表示方法に関する若干の挙動——だけで、いずれも素早く解決しました。新しいモデルが公開されて数日後に、新しい NVIDIA DGX Spark デバイス上でそれほど苦労せず動かせたのは素晴らしいことだと思います。## Llama 3.1
70B LoRA 学習

NVIDIA Spark [page](https://www.nvidia.com/en-us/products/workstations/dgx-spark/)
NVIDIA Spark page
今回はフルファインチューニングではなく、標準的な LoRA 学習ランを選びました。より大きなモデルも試せたかもしれませんが、これはあくまで「このプロセスが機械的にどれくらいスムーズに動くか」を確認するための概念実証です。### 手法 別の実験のために作成した小規模データセット(2K サンプル)を使って DGX Spark 上でこのプロセスがどれくらいうまく機能するかをベンチマークしました。Jupyter Notebook で組んでいたパイプラインを Docker コンテナベースのパイプラインに移行しています。参考にしたのは NVIDIA が公開している [unsloth training in Pytorch](https://build.nvidia.com/spark/unsloth) のプレイブックです。Docker コンテナの設定方法と全体のセットアップを把握するのに役立ちました。あとは自分で作ったカスタムデータセットを差し込むだけでした。あまり重要ではありませんが、このデータセットは小さなクエリ分解モデルを学習させるために生成したものです。ユーザーが送信したクエリが RAG バックエンドが持つアイテムとうまく合致しない場合があるため、メインクエリを N 個の検索クエリに分解するタスクをモデルに学習させるという発想です。## 学習と推論 Docker コンテナ周りの定番の問題(どのバージョンの Pytorch が何と相性が良いかの確認)を乗り越えれば、学習プロセス自体は順調でした。バッチサイズ 64 で 340 バッチ(10 エポック)を処理するのに約 8.5 時間かかりました。予想どおりモデルはデータに過学習しましたが、目的はプロセスのスムーズさを確認することだったので問題ありません。新しいケースで試してみると、モデルはそれなりに期待どおりの動作をします。精度が高いかと言われれば……いいえ、でもそれはテスト用に作ったデータセットの問題がほとんどです。モデルはクエリを受け取り、推論と分解されたクエリフィールドを含む JSON レスポンスを生成することを学習します。以下は結果をパースした後の出力例です。```prompt Input: How do I learn machine learning while working full-time as a software engineer? Reasoning: User need combines professional education, technology field learning, and time management for working engineers. Decomposed queries: ['machine learning learning plans', 'full-time work balance learning', 'software engineer education', 'time management for learning'] ``` モデルは 4 bit 量子化で約 37GB で、モデルと学習合わせて 128GB 中約 74GB を使用しました。これはより大きなモデルでも試せる余地があることを意味しますが、ドキュメントで謳われているような 200B パラメータモデルが収まるかどうかは不明です。それでも、これまで 70B パラメータのモデルで学習ランを簡単に回せたことはほとんどなかったので、新鮮な体験でした。### Llama 70B LoRA 学習 まとめ 前回と同様、これがおそらく最速の方法ではありませんが、128GB の統合 RAM のおかげでこの種の作業を物理的に実行しやすくなっているのは確かです。70B パラメータモデル向けのアダプターを社内で大した苦労もなく学習させられるというのは素晴らしいことです。学習中のピーク使用メモリは 128GB 中 74GB に留まっており、より大きなモデルの学習や、より込み入った設定を試す余地がまだあります。[AIXplore](https://publish.obsidian.md/aixplore/Practical+Applications/dgx-lab-benchmarks-vs-reality-day-4#What's+Production-Ready) の記事を読むと、FP16 推論に関する問題をいくつか運よく回避できていたようです。モデルのサイズを考えて 4 bit 量子化のままにしておいたのが功を奏しました。著者らが指摘するもうひとつの問題は、50 トレーニングステップごとにキャッシュを手動でクリアする必要があったというものです。Unsloth がこれを内部で処理しているのだと思います。というのも `Unsloth: Will smartly offload gradients to save VRAM!` という警告が表示されていたからです。## まとめ NVIDIA DGX Spark に早期アクセスできたことは、ライフサイクルの早い段階で面白いハードウェアを触れる楽しい経験でした。128GB の統合メモリへのアクセスという面では価格設定もなかなか良く、エコシステムが適切にサポートされれば生成速度と学習速度の改善が見込まれ、全体的な性能が底上げされるでしょう。私個人としては、必要に応じてより大きなモデルを社内で学習・ホストできる環境があるのはありがたく、LLM 活用の際に生じる様々な煩わしさを軽減してくれます。今後のパイプラインの中で DGX Spark をどう最大限活用できるか、引き続き模索していきたいと思います。### 付録: ### DeepSeek OCR 用 Dockerfile ``` # DeepSeek-OCR using NVIDIA PyTorch 25.09 # container NVIDIA DGX Spark プレイブックのアプローチに従う FROM nvcr.io/NVIDIA/pytorch:25.09-py3 # 環境変数を設定 ENV DEBIAN_FRONTEND=noninteractive ENV PYTHONUNBUFFERED=1 LABEL maintainer="DeepSeek-OCR Pipeline" LABEL description="NVIDIA PyTorch container with DeepSeek-OCR for vision-language OCR" # PyTorch は CUDA サポート付きでこのコンテナに既にインストール済み # DeepSeek-OCR 固有の依存関係をインストール # # 注意: DeepSeek-OCR との互換性のため transformers 4.46.3 が必要 RUN pip install --no-cache-dir \ 'transformers==4.46.3' \ 'tokenizers==0.20.3' \ accelerate \ pillow \ requests \ huggingface_hub \ einops \ addict \ easydict \ matplotlib \ timm # インストール確認 RUN python3 -c "import torch; print(f'PyTorch: {torch.**version**}')" && \ python3 -c "import transformers; print(f'Transformers: {transformers.**version**}')" && \ python3 -c "import torch; print(f'CUDA available: {torch.cuda.is_available()}')" && \ echo "✓ All packages installed successfully" # 作業ディレクトリを設定 WORKDIR /workspace # デフォルトコマンド CMD ["/bin/bash"] ```

他の記事

14 ページ · hugo 0.148.2 · f5ab6db · 構築済み Aug 10 22:58
2389 Radio
2389 RADIO ステーションを選択