---
sidebar_position: 2
title: DGX SparkでGUI操作動画解析システムを作る
description: NVIDIA DGX SparkでQwen3-VLとLanceDBを使ったGUI操作動画解析システムの構築方法
hide_table_of_contents: false
displayed_sidebar: null
image: ./banner.png
---

# DGX Sparkで作る！GUI操作動画解析システム

Qwen3-VL + LanceDBでサーバー設定作業を自動ドキュメント化

## はじめに

サーバーの設定作業をGUIで行う場面、意外と多いですよね。WebUIでの管理画面操作、設定ウィザードの実行...。後から「あの時どう設定したっけ？」と振り返りたいことがあります。

この記事では、**NVIDIA DGX Spark**を使って、GUI操作の録画動画から設定内容を自動抽出し、検索・マニュアル生成ができるシステムを構築します。

### 作るもの

- **入力**: GUI操作を録画したMP4動画
- **処理**: フレーム抽出 → VLMで画面解析 → ベクトルDB格納
- **出力**: 設定値の検索、操作手順のマニュアル生成

### 使用技術

| コンポーネント | 技術 |
|---------------|------|
| ハードウェア | NVIDIA DGX Spark (128GB統合メモリ) |
| VLM | Qwen3-VL 8B (Ollama) |
| フレーム抽出 | OpenCV + SSIM |
| ベクトルDB | LanceDB |
| WebUI | Gradio |

## DGX Sparkとは

NVIDIA DGX Sparkは、デスクトップサイズの「AIスーパーコンピュータ」です。

### スペック

| 項目 | 仕様 |
|------|------|
| CPU | ARM64 20コア (Cortex-X925 x10 + Cortex-A725 x10) |
| GPU | NVIDIA GB10 (Blackwell) - 6144 CUDA Cores |
| メモリ | 128GB 統合メモリ (CPU/GPU共有) |
| OS | Ubuntu 24.04 LTS |

### 開発上のポイント

1. **統合メモリアーキテクチャ (UMA)**: CPUとGPUがメモリを共有。大規模モデルが載りやすい
2. **ARM64**: x86のwheelは使えない。ARM64ビルドを使用
3. **Ollama対応**: すぐ動く。公式サポート済み

## システム構成

```
GUI操作動画(MP4)
      │
      ▼
① フレーム抽出 (OpenCV + SSIM)
      │ 画面変化を検出し重要フレームのみ抽出
      ▼
② Qwen3-VL 8B (Ollama)
      │ 各フレームの画面内容を解析
      │ 設定項目・値・操作内容を抽出
      ▼
③ LanceDB
      │ 解析結果をベクトルインデックス化
      ▼
④ Gradio WebUI
      └─ 検索・マニュアル生成
```

## 環境構築

### 前提条件

- DGX Sparkにssh接続可能
- Ollamaインストール済み

### セットアップ

```bash
# プロジェクトディレクトリ作成
mkdir -p ~/projects/video-config-analyzer
cd ~/projects/video-config-analyzer

# 仮想環境作成
python3 -m venv venv
source venv/bin/activate

# 依存パッケージインストール
pip install opencv-python-headless gradio lancedb sentence-transformers \
    pillow pyyaml requests numpy tqdm scikit-image pyarrow

# Qwen3-VLモデル取得（未取得の場合）
ollama pull qwen3-vl:8b-instruct
```

## 実装解説

### 1. フレーム抽出 (frame_extractor.py)

動画から「画面が変化した」フレームのみを抽出します。

```python
from skimage.metrics import structural_similarity as ssim
import cv2

def extract_keyframes(video_path, threshold=0.95):
    """SSIMで画面変化を検出し、変化があったフレームのみ抽出"""
    cap = cv2.VideoCapture(video_path)
    prev_frame = None
    keyframes = []
    
    while True:
        ret, frame = cap.read()
        if not ret:
            break
        
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        
        if prev_frame is None:
            keyframes.append(frame)
            prev_frame = gray
            continue
        
        # SSIM計算
        score = ssim(prev_frame, gray)
        if score < threshold:  # 変化検出
            keyframes.append(frame)
            prev_frame = gray
    
    return keyframes
```

:::tip ポイント
SSIM (Structural Similarity Index) を使うことで、わずかなノイズに反応せず、実際の画面遷移のみを検出できます。
:::

### 2. VLM解析 (vlm_analyzer.py)

Ollama経由でQwen3-VLを呼び出し、画面内容を解析します。

```python
import base64
import requests

def analyze_frame(image_path, ollama_url="http://localhost:11434"):
    """フレームをVLMで解析し、設定情報を抽出"""
    with open(image_path, "rb") as f:
        image_b64 = base64.b64encode(f.read()).decode()
    
    prompt = """この画像はサーバー設定画面です。以下をJSON形式で抽出:
    {
      "screen_title": "画面タイトル",
      "visible_settings": [{"name": "設定名", "value": "値", "type": "タイプ"}],
      "buttons_visible": ["ボタン名リスト"],
      "current_action": "操作の説明"
    }"""
    
    response = requests.post(f"{ollama_url}/api/generate", json={
        "model": "qwen3-vl:8b-instruct",
        "prompt": prompt,
        "images": [image_b64],
        "stream": False
    })
    
    return response.json()["response"]
```

### 3. インデックス化 (indexer.py)

LanceDBで解析結果をベクトル化して保存。後から自然言語で検索可能に。

```python
import lancedb
from sentence_transformers import SentenceTransformer

class VideoIndexer:
    def __init__(self, db_path="./data/lancedb"):
        self.db = lancedb.connect(db_path)
        self.embedder = SentenceTransformer("all-MiniLM-L6-v2")
    
    def index(self, analysis_results, video_id):
        """解析結果をベクトルインデックスに追加"""
        entries = []
        for result in analysis_results:
            text = f"{result['screen_title']} {result['current_action']}"
            vector = self.embedder.encode(text).tolist()
            entries.append({
                "video_id": video_id,
                "text": text,
                "vector": vector,
                **result
            })
        
        table = self.db.create_table("video_analysis", entries, mode="overwrite")
        return len(entries)
```

### 4. WebUI (web_ui.py)

Gradioで直感的なインターフェースを提供。

```python
import gradio as gr

def create_ui(pipeline):
    with gr.Blocks(title="Video Config Analyzer") as app:
        gr.Markdown("# GUI操作動画解析システム")
        
        with gr.Tab("動画解析"):
            video_input = gr.File(label="動画ファイル (MP4)")
            analyze_btn = gr.Button("解析開始")
            status = gr.Textbox(label="ステータス")
        
        with gr.Tab("検索"):
            query = gr.Textbox(label="検索クエリ")
            search_btn = gr.Button("検索")
            results = gr.Dataframe()
        
        with gr.Tab("マニュアル生成"):
            video_select = gr.Dropdown(label="動画選択")
            generate_btn = gr.Button("生成")
            manual_output = gr.Markdown()
    
    return app
```

## WebUIの起動

```bash
cd ~/projects/video-config-analyzer
source venv/bin/activate
python app/web_ui.py
```

WebUIは http://localhost:7860 でアクセスできます。

## トラブルシューティング

### Q: Ollamaが応答しない

```bash
# Ollamaサービス確認
systemctl status ollama

# モデル確認
ollama list | grep qwen3-vl
```

### Q: メモリ不足エラー

DGX Sparkの統合メモリを活用するため、他のプロセスを停止して試してください。

```bash
# GPU使用状況確認
nvidia-smi

# 不要なプロセス停止
pkill -f "python.*some_heavy_process"
```

### Q: ARM64用パッケージが見つからない

一部のPyPIパッケージはARM64用wheelがない場合があります。その場合はソースからビルド:

```bash
pip install --no-binary :all: パッケージ名
```

## まとめ

DGX Sparkの統合メモリアーキテクチャは、VLMを使った画像解析タスクに最適です。128GBの大容量メモリにより、8Bパラメータのモデルも余裕で動作します。

このシステムを使えば、GUI操作の録画を後から検索可能なドキュメントに変換できます。

### 今後の改善案

- **OmniParser V2の統合**: GUI要素の検出精度向上
- **バッチ処理**: 複数動画の一括処理
- **差分検出の高度化**: 動的なコンテンツの除外

## 参考リンク

- [NVIDIA DGX Spark](https://www.nvidia.com/en-us/products/workstations/dgx-spark/)
- [Qwen3-VL](https://github.com/QwenLM/Qwen-VL)
- [LanceDB](https://lancedb.github.io/lancedb/)
- [Gradio](https://gradio.app/)
- [Python on NVIDIA DGX Spark: First Impressions (Anaconda)](https://www.anaconda.com/blog/python-nvidia-dgx-spark-first-impressions)

---

*この記事は2026年2月時点の情報です。*
