All checks were successful
Deploy Docusaurus Site / deploy (push) Successful in 30s
296 lines
8.6 KiB
Markdown
296 lines
8.6 KiB
Markdown
---
|
||
sidebar_position: 2
|
||
title: DGX SparkでGUI操作動画解析システムを作る
|
||
description: NVIDIA DGX SparkでQwen3-VLとLanceDBを使ったGUI操作動画解析システムの構築方法
|
||
hide_table_of_contents: false
|
||
displayed_sidebar: null
|
||
---
|
||
|
||
# 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月時点の情報です。*
|