0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Ryzen AI MAX+ 395でNemotron 3.5 Super VLを動かす:画像・動画認識とQwen3.6・Boltの速度比較

0
Posted at

AMD Ryzen AI MAX+ 395の内蔵GPU、Radeon 8060Sで、NVIDIA Nemotron 3.5 Super VL 120B-A12BのGGUFを動かしました。96 GBの共有メモリ環境で、テキスト生成、PNG/JPEGの認識、複数画像による時系列理解、MP4入力を検証しています。

テキスト生成は約19.2 tokens/s、短文の初回応答時間は約0.52秒でした。画像では図形・色・文字を認識でき、4秒の合成動画では移動方向や物体の出現を回答できました。ただし、動画の出現時刻を1秒早く答える誤認識もありました。

この記事には、2026年10月18日の実行条件、再現用コマンド、認識結果、メモリ使用量を記載します。Qwen3.6の2モデル、Nemotron 3.5 Boltとの同一条件での速度比較も行いました。

検証環境とモデル

NVIDIAの公式BF16モデルを基にした、AtomicChat配布のGGUFを使用しました。言語モデル本体はAD-IQ3_XXS、画像用のエンコーダーとprojectorはF16版です。

項目 構成
CPU AMD Ryzen AI MAX+ 395
GPU Radeon 8060S、gfx1151
共有メモリ 96 GB構成、OSのMemTotalは約90.7 GiB
OS Ubuntu 26.04.1 LTS
ROCm環境 /opt/rocm/core-10.1配下のHIPコンパイラーを使用
コンパイラー表示 HIP 7.16.26385、AMD clang 24.0.0git
llama.cpp build 11716、コミット797de63b2fa7396dcc8caca76834c699ac84e1c3
言語モデル Nemotron 3.5 Super VL 120B-A12B、AD-IQ3_XXS
mmproj mmproj-NVIDIA-Nemotron-3.5-Super-VL-120B-A12B-F16.gguf

ROCmの配置ディレクトリ名とhipcc --versionの表示は上表のとおりです。この構成での動作確認であり、別のROCmバージョンやOSまで検証したものではありません。容量は、GBを10進、GiBを2進として区別しています。

Super VLへの対応は、llama.cppのPR #30520で2026年10月15日にマージされています。対応コミットはcd0a5b6a180dff0048e5fd993098b21c0b2c91b8で、今回のビルドにはこの変更が含まれます。GGUFメタデータでは、言語モデルがnemotron_h_moe、画像projectorがnemotron_omniとなっていました。

GGUFとmmprojの取得

取得するファイルは次の3つです。分割GGUFは2つとも必要ですが、起動時に指定するのは1つ目です。

ファイル 容量
NVIDIA-Nemotron-3.5-Super-VL-120B-A12B-AD-IQ3_XXS-00001-of-00002.gguf 約44.57 GB
NVIDIA-Nemotron-3.5-Super-VL-120B-A12B-AD-IQ3_XXS-00002-of-00002.gguf 約20.76 GB
mmproj-NVIDIA-Nemotron-3.5-Super-VL-120B-A12B-F16.gguf 約1.73 GB
合計 約67.06 GB

以下のコマンド例では、説明用の作業ディレクトリを新しく作成し、モデルをmodelsに配置します。ROCm、CMake、Git、Hugging Face CLIのhf、FFmpeg/FFprobeは導入済みを前提とします。

mkdir supervl-demo
cd supervl-demo

hf download \
  AtomicChat/NVIDIA-Nemotron-3.5-Super-VL-120B-A12B-GGUF \
  --revision 119686c3e0821b5234c7f3d557b5d40dc1341a9d \
  --include '*-AD-IQ3_XXS-*.gguf' \
            'mmproj-NVIDIA-Nemotron-3.5-Super-VL-120B-A12B-F16.gguf' \
  --local-dir models

実験では取得後に3ファイルのSHA-256を配布元のメタデータと照合し、一致を確認しました。約67 GBはファイルの合計容量で、実行時には別途KVキャッシュ、画像処理用バッファ、ランタイムなどのメモリが必要です。

llama.cppをHIPでビルドする

既存の推論環境を変更せず、専用のソースとビルドディレクトリを用意しました。llama.cppのソースコードには変更を加えていません。

git clone https://github.com/ggml-org/llama.cpp.git
git -C llama.cpp checkout --detach 797de63b2fa7396dcc8caca76834c699ac84e1c3

export ROCM_PATH=/opt/rocm/core-10.1
export HIP_PATH="$ROCM_PATH"
export PATH="$ROCM_PATH/bin:$ROCM_PATH/lib/llvm/bin:$PATH"

cmake -S llama.cpp -B build-hip \
  -DCMAKE_BUILD_TYPE=Release \
  -DGGML_HIP=ON \
  -DAMDGPU_TARGETS=gfx1151 \
  -DCMAKE_HIP_ARCHITECTURES=gfx1151 \
  -DGGML_HIP_NO_VMM=ON \
  -DMTMD_VIDEO=ON \
  -DLLAMA_SUBPROCESS=ON \
  -DLLAMA_BUILD_TESTS=OFF

cmake --build build-hip -j 12 --target llama-mtmd-cli llama-server
build-hip/bin/llama-server --list-devices
build-hip/bin/llama-mtmd-cli --help

MTMD_VIDEOとLLAMA_SUBPROCESSは、FFmpegを起動する動画入力経路のために有効にしています。今回のGPUターゲットはgfx1151です。別のGPUでは、そのデバイスに対応するターゲットを指定する必要があります。

以降の起動例では、ファイル名を短く扱うために変数を定義します。

MODEL=models/NVIDIA-Nemotron-3.5-Super-VL-120B-A12B-AD-IQ3_XXS-00001-of-00002.gguf
MMPROJ=models/mmproj-NVIDIA-Nemotron-3.5-Super-VL-120B-A12B-F16.gguf

画像・動画用サーバーの起動

まず小さな入力で確認するため、コンテキストを8192、画像を1枚256トークン、動画を1fpsに設定しました。

build-hip/bin/llama-server \
  -m "$MODEL" --mmproj "$MMPROJ" \
  -ngl 999 -c 8192 -np 1 \
  -b 512 -ub 512 -t 16 \
  --image-min-tokens 256 --image-max-tokens 256 \
  --video-fps 1 --video-timestamp-interval 1000 \
  --jinja --reasoning off \
  --host 127.0.0.1 --port 18081 \
  --metrics -lv 4

起動ログのうち、GPU配置に関係する部分を抜粋します。時刻などの接頭辞は省略しました。

load_tensors: offloaded 90/90 layers to GPU
load_tensors:        ROCm0 model buffer size = 59742.52 MiB
load_tensors:    ROCm_Host model buffer size =   544.00 MiB
llama_kv_cache:      ROCm0 KV buffer size =    64.00 MiB
llama_memory_recurrent:      ROCm0 RS buffer size =   164.69 MiB
clip_ctx: CLIP using ROCm0 backend
load_hparams: projector:          nemotron_omni

言語モデルは90/90層がGPUに配置され、画像エンコーダーにもROCm0が使われました。ホスト側バッファや画像前処理もあるため、これを「すべての処理がGPUだけで実行された」とは解釈していません。

MTP用のblk.88テンソルが未使用という警告も出ました。今回の推論では投機的デコーディングを有効にしていません。

静止画の色・図形・文字を認識する

認識結果を確認しやすいよう、白背景に3つの図形と文字を置いた512×512画像を使いました。PNGとJPEGは同じ内容です。

対象 正解
左上 赤い円
右上 青い四角
下中央 緑の三角
上部の文字 VISION TEST 42

同じ配置の画像を作るコードは以下です。Pillowを使用します。

from PIL import Image, ImageDraw, ImageFont

image = Image.new("RGB", (512, 512), "white")
draw = ImageDraw.Draw(image)
font = ImageFont.truetype(
    "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 30
)
draw.text((55, 20), "VISION TEST 42", fill="black", font=font)
draw.ellipse((60, 130, 180, 250), fill="#e32636")
draw.rectangle((290, 130, 410, 250), fill="#205de0")
draw.polygon([(256, 310), (180, 440), (332, 440)], fill="#129c48")
image.save("shapes.png")
image.save("shapes.jpg", quality=95)

APIでは画像をBase64で送信しました。Python標準ライブラリでリクエストする最小例を示します。これは応答を一括で受け取る例で、TTFTの計測コードとは別です。

import base64
import json
import urllib.request

with open("shapes.png", "rb") as f:
    encoded = base64.b64encode(f.read()).decode()

content = [
    {"type": "image_url", "image_url": {
        "url": "data:image/png;base64," + encoded
    }},
    {"type": "text", "text": (
        "List the three colored shapes and their positions. "
        "Then transcribe the text exactly. Answer briefly."
    )},
]
payload = {
    "messages": [{"role": "user", "content": content}],
    "temperature": 0, "seed": 42, "max_tokens": 160,
    "cache_prompt": False,
    "chat_template_kwargs": {"enable_thinking": False},
}
request = urllib.request.Request(
    "http://127.0.0.1:18081/v1/chat/completions",
    data=json.dumps(payload).encode(),
    headers={"Content-Type": "application/json"},
)
with urllib.request.urlopen(request, timeout=600) as response:
    result = json.load(response)
print(result["choices"][0]["message"]["content"])

PNG、JPEGともに次の回答を得ました。

Red circle: top left. Blue square: top right. Green triangle: bottom center.

VISION TEST 42

図形・色・配置・文字はいずれも正解で、2回の検証でも同じ回答になりました。以下は2回目の計測値です。TTFTはリクエスト送信から最初の本文まで、全応答時間は送信から応答終了までを測っています。モデルロード時間は含めません。

入力 TTFT 全応答時間 生成速度
PNG 1.44秒 2.69秒 19.18 tokens/s
JPEG 1.53秒 2.81秒 18.73 tokens/s

この結果は、合成画像による基本的な認識確認です。自然画像や複雑なOCRの精度を示す評価ではありません。

CLIでも次の形式で画像を渡せます。今回も実行し、文字と3つの図形の正答、終了コード0を確認しました。CLIはモデル本来のthinking設定を使ったため、上表のreasoning offのAPI測定とは速度を比較していません。

build-hip/bin/llama-mtmd-cli \
  -m "$MODEL" --mmproj "$MMPROJ" \
  -ngl 999 -c 8192 -b 512 -ub 512 -t 16 -n 256 \
  --image-min-tokens 256 --image-max-tokens 256 \
  --jinja --image shapes.png \
  -p 'List the colored shapes and read the text. Answer briefly.'

4秒の動画で移動方向と出現時刻を確認する

動画用には、512×512、8fps、4秒の合成MP4を用意しました。赤い円が左から右へ水平移動し、青い四角が2秒に初めて現れます。正解が決まっている素材を使い、入力順序と時刻に対応した回答が得られるかを確認しました。

検証動画を生成する短いコード例

上の静止画生成コードと同じPillowのフォントを使い、PNG列をFFmpegでMP4に変換します。

from pathlib import Path
import subprocess
from PIL import Image, ImageDraw, ImageFont

frames = Path("source-frames")
frames.mkdir(exist_ok=True)
font = ImageFont.truetype(
    "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 30
)
for i in range(32):
    image = Image.new("RGB", (512, 512), "white")
    draw = ImageDraw.Draw(image)
    draw.text((65, 25), "MOTION TEST", fill="black", font=font)
    x = 80 + round(352 * i / 31)
    draw.ellipse((x - 36, 210, x + 36, 282), fill="#e32636")
    if i >= 16:
        draw.rectangle((370, 350, 450, 430), fill="#205de0")
    image.save(frames / f"{i:03d}.png")

subprocess.run([
    "ffmpeg", "-y", "-v", "error", "-framerate", "8",
    "-i", "source-frames/%03d.png", "-c:v", "libx264",
    "-pix_fmt", "yuv420p", "-movflags", "+faststart", "motion.mp4",
], check=True)

OpenCVで抽出した4画像をまとめて渡す

最初にOpenCVで0、1、2、3秒の4フレームを抽出しました。処理の要点は次のとおりです。

import cv2

cap = cv2.VideoCapture("motion.mp4")
fps = cap.get(cv2.CAP_PROP_FPS)
if not cap.isOpened() or fps <= 0:
    raise RuntimeError("動画を開けないか、FPSを取得できません")

index, next_sample = 0, 0.0
try:
    while next_sample < 4:
        ok, frame = cap.read()
        if not ok:
            break
        timestamp = index / fps
        if timestamp + 1e-9 >= next_sample:
            cv2.imwrite(f"frame-{next_sample:.0f}s.jpg", frame)
            next_sample += 1.0
        index += 1
finally:
    cap.release()

APIのcontentには、「Frame 1, timestamp 0.0 seconds:」というテキスト、0秒の画像、次の時刻テキスト、次の画像、という順序で4枚を格納しました。各画像を別々に説明させて文章だけを要約する方式ではなく、4枚を1回の推論に渡しています。

質問は次のとおりです。

These frames are in chronological order. Which direction does the red circle move?
At what timestamp does the blue square first appear, or is it present from the first frame?
Answer briefly based only on the frames.

正順での回答は次のようになりました。

The red circle moves diagonally down and to the right.
The blue square first appears at timestamp 2.0 seconds.

右向きの移動と2秒の出現は合っていますが、実際には上下に動いていません。「斜め下」という余分な動きを回答しています。

次に、4枚の画像を逆順にし、時刻を0秒から振り直して同じ質問をしました。

The red circle moves to the left.
The blue square is present from the first frame.

入力順を反転すると、移動方向が左向きに変わり、青い四角も最初から存在すると回答しました。少なくとも今回の単純な例では、画像列の順序に応じて回答が変わっています。

MP4をAPIに渡す

llama.cppにはFFmpegで動画をフレーム化する実装があり、サーバーAPIのinput_videoを使えます。MP4を入力できますが、モデルが動画コンテナを直接解釈するわけではなく、内部で画像列に変換されます。

前述の画像APIの例では、contentを次のように置き換えればMP4を渡せます。payloadの構造や送信先は同じです。

with open("motion.mp4", "rb") as f:
    encoded = base64.b64encode(f.read()).decode()

content = [
    {"type": "input_video", "input_video": {"data": encoded}},
    {"type": "text", "text": (
        "Describe the motion of the red circle. "
        "At what time does the blue square first appear? "
        "Answer briefly using the timestamps."
    )},
]

通常の質問では、2回とも次の回答になりました。

The red circle moves from left to right.
The blue square first appears at 1.00s.

移動方向は正解ですが、出現時刻を1秒早く答えています。今回使用した動画入力の実装を確認すると、タイムスタンプのテキストは各フレーム画像の後に挿入されます。そこで、追加検証では質問を次のように変更しました。

For each of the four sampled video frames, list the frame number in order,
its timestamp, the red circle position (left, center-left, center-right, right),
and whether a blue square is visible.
Read each timestamp as the time of the image immediately before it.
Then state when the blue square first appears.

この質問では、以下の対応を正しく回答しました。

フレーム 回答時刻 赤い円の位置 青い四角
1 00:00 左 なし
2 00:01 中央左 なし
3 00:02 中央右 あり
4 00:03 右 あり

タイムスタンプと画像の対応を明示した質問では改善しましたが、質問の詳しさも変えているため、挿入位置だけが誤答の原因だとは断定できません。動画内の時刻を扱う用途では、正解データとの照合が必要です。

動画入力の応答時間

入力 TTFT 全応答時間 生成速度
正順4フレーム 4.78秒 6.11秒 18.76 tokens/s
逆順4フレーム 4.79秒 5.76秒 18.52 tokens/s
MP4、通常質問 4.91秒 6.14秒 17.89 tokens/s
MP4、各フレームの時刻を明示した質問 4.76秒 10.12秒 19.03 tokens/s

これは1回目の確認に続けて行った2回目の計測値で、3回平均や中央値ではありません。最後の質問は103トークンを生成しており、通常質問の23トークンより回答が長いため、全応答時間も増えています。

動画は4秒、512×512、1fps抽出という小さな条件です。長時間・高解像度の動画や、人物の行動認識は今回評価していません。

画像・動画推論のメモリ使用量

画像・動画用サーバーでは、0.5秒ごとにRSS、MemAvailable、GTT、VRAM、GPU使用率を記録しました。主要な値を示します。

段階 プロセスRSS最大 GTT最大 MemAvailable最小
ロード済み待機 1.14 GiB 60.67 GiB 24.01 GiB
PNG処理 1.55 GiB 60.83 GiB 23.58 GiB
JPEG処理 2.06 GiB 60.83 GiB 22.94 GiB
正順4画像 2.57 GiB 60.83 GiB 22.49 GiB
逆順4画像 3.09 GiB 60.83 GiB 21.85 GiB
MP4、通常質問 3.58 GiB 60.83 GiB 21.66 GiB
MP4、詳細質問 3.58 GiB 60.83 GiB 21.59 GiB

GTTとVRAMはシステム全体のGPUメモリカウンターで、ほかのプロセスの分も含みます。APUの共有メモリ上の割り当てを含むため、RSS・GTT・VRAMを単純に足して総使用量にすることはできません。RSSが数GiBだから数GiBで動く、という解釈もできません。

開始時のMemAvailableは約85.94 GiB、測定中の最低値は約21.59 GiBで、差は約64.35 GiBでした。この差もモデル以外の活動に影響されますが、96 GB構成で今回の処理を実行できた際のメモリ余裕の目安になります。

後半ほどRSSが増えているのは、同じサーバーでリクエストを順次処理した際の値です。サーバーは再帰状態のチェックポイントも保持するため、各入力を単独で起動した場合の必要量とは一致しません。長時間の反復処理でメモリ使用量が収束するかは未検証です。

GPU使用率の観測最大は99%で、2回のAPI検証にOOM、ROCmエラー、異常終了はありませんでした。HTTP受付可能になるまでは25.05秒と32.13秒でしたが、ディスクキャッシュの状態を揃えたコールドロード比較ではありません。

テキストLLMとしてQwen3.6・Boltと比較する

Super VLに画像を与えず、テキストLLMとしても比較しました。画像用サーバーを停止してから、4モデルを同じllama-serverで1つずつ起動しています。テキスト測定ではmmprojをロードしていません。

比較条件

項目 設定
llama.cpp、ROCm 全モデルで同じビルド・実行環境
GPU配置 全層オフロードをログで確認
コンテキスト 8192
同時スロット 1
バッチ/マイクロバッチ 512/512
CPUスレッド 通常・入力処理とも16
Flash Attention on
thinking off
MTPを含む投機的デコーディング 無効
temperature/seed 0/42
生成上限 キャッシュなし128、キャッシュあり32トークン
測定回数 ウォームアップ後、各条件3回

共通の起動オプションは以下です。MODELを比較対象のGGUFに切り替え、モデルごとにサーバーを起動し直しました。

build-hip/bin/llama-server \
  -m "$MODEL" -ngl 999 \
  -c 8192 -np 1 -b 512 -ub 512 -t 16 -tb 16 \
  -fa on -fit off --spec-type none \
  --jinja --reasoning off --perf \
  --host 127.0.0.1 --port 18082 -lv 4

比較したGGUF構成は次のとおりです。Dense/MoE、規模、量子化方式が異なるため、量子化条件を揃えたモデル系列単体の比較ではありません。

モデル 使用ファイル/量子化 GPU配置
Qwen3.6-35B-A3B Qwen3.6-35B-A3B-UD-Q4_K_XL.gguf 41/41層
Qwen3.6-27B Qwen3.6-27B-MTP-Q8_0.gguf、MTPは無効 66/66層
Nemotron 3.5 Bolt 74B-A9B NVIDIA-Nemotron-3.5-Bolt-74B-A9B-24GB.gguf 89/89層
Nemotron 3.5 Super VL 120B-A12B AD-IQ3_XXS、2分割GGUF 90/90層

入力とTTFTの測り方

短文は写真コレクションの整理とバックアップについて、600語以上のガイド作成を依頼する同一の英文です。長文では次の記録文を反復し、末尾にセンサーデータの保存・検証・バックアップのガイド作成を依頼しました。

The archive contains a numbered record of a routine sensor reading.

長文の反復数は、各モデルの/tokenizeで本文が約2048、約7168トークンになるよう二分探索で調整しています。そのため、モデル間で質問と反復文は共通ですが、長文全体の文字列は完全同一ではありません。チャットテンプレート込みの実入力数は次のとおりです。

モデル群 短文 約2K 約7K
Qwen3.6の2モデル 56 2053 7177
Bolt、Super VL 62 2059 7183

TTFTは、localhostへHTTPリクエストを送信する直前から、SSEで最初の空でない本文を受け取るまでを測りました。roleだけのイベントは数えません。モデルロードと短いウォームアップは測定から除外しています。

計測コードの中心部分を示します。サーバーの自動起動・終了、入力長の調整、生イベントの保存、集計処理は省略しています。

import json
import time
import urllib.request

def measure(prompt, max_tokens=128, cache=False):
    payload = {
        "messages": [{"role": "user", "content": prompt}],
        "temperature": 0, "seed": 42, "max_tokens": max_tokens,
        "stream": True, "stream_options": {"include_usage": True},
        "cache_prompt": cache, "timings_per_token": True,
        "chat_template_kwargs": {"enable_thinking": False},
    }
    request = urllib.request.Request(
        "http://127.0.0.1:18082/v1/chat/completions",
        data=json.dumps(payload).encode(),
        headers={"Content-Type": "application/json"},
    )
    opener = urllib.request.build_opener(urllib.request.ProxyHandler({}))
    first, timings = None, None
    start = time.perf_counter()
    with opener.open(request, timeout=600) as response:
        for line in response:
            if not line.startswith(b"data: "):
                continue
            data = line[6:].strip()
            if data == b"[DONE]":
                break
            event = json.loads(data)
            for choice in event.get("choices", []):
                if choice.get("delta", {}).get("content") and first is None:
                    first = time.perf_counter() - start
            timings = event.get("timings") or timings
    return first, timings["predicted_per_second"], timings.get("cache_n", 0)

生成速度はサーバーのtimings.predicted_per_secondを使います。キャッシュなしの全試行で、実際に128トークンを生成してlengthで終了し、cache_n=0であることを確認しました。

生成速度とキャッシュなしTTFT

次表は各3回の中央値です。生成速度の単位はtokens/s、TTFTの単位は秒です。

モデル 短文生成 短文TTFT 約2K TTFT 約7K TTFT 約7K生成
Qwen3.6-35B-A3B/UD-Q4_K_XL 50.47 0.148 1.406 4.917 48.72
Qwen3.6-27B/Q8_0 7.74 0.413 5.660 19.783 7.56
Nemotron 3.5 Bolt/24GB版 30.59 0.311 3.683 12.405 30.28
Nemotron 3.5 Super VL/AD-IQ3_XXS 19.20 0.517 6.272 20.053 19.12

今回の構成では、Super VLの生成速度はBoltの約63%でした。約7Kの入力でも生成速度はほぼ維持していますが、最初の本文が出るまでには約20秒かかっています。短い質問への応答と、長い文書を毎回読み直す用途では待ち時間が異なります。

Qwen3.6-35B-A3Bは今回の4構成で最も高速でした。一方、Qwen3.6-27BのQ8_0版は約7.7 tokens/sです。規模の名前だけで速度を判断せず、Dense/MoEや量子化形式を含めて比較する必要があります。今回の測定だけで、速度差の要因を個別に切り分けたとはいえません。

約7K入力のばらつきは次のとおりです。

モデル TTFT 3回(秒) 生成速度3回(tokens/s)
Qwen3.6-35B-A3B 4.914、4.917、4.922 48.75、48.72、48.69
Qwen3.6-27B 19.761、19.785、19.783 7.56、7.56、7.56
Bolt 12.360、12.405、12.432 30.32、30.28、30.25
Super VL 20.036、20.060、20.053 19.12、19.15、19.12

同一長文をキャッシュした場合

同じ約7Kプロンプトを同じスロットで繰り返す条件も測りました。キャッシュを有効にしたリクエストで準備した後、生成上限32トークンで3回測定しています。

モデル キャッシュなしTTFT キャッシュありTTFT 実際の再利用トークン数
Qwen3.6-35B-A3B 4.917秒 0.064秒 7173
Qwen3.6-27B 19.783秒 0.197秒 7173
Bolt 12.405秒 0.097秒 7179
Super VL 20.053秒 0.133秒 7179

全モデルで3回とも上表のトークン数の再利用を確認しました。Super VLでも、同一長文の再利用ならTTFTは約0.13秒に短縮しています。

これは同じ入力を同じスロットで繰り返した場合です。新しい文書、内容が増えた会話、別のクライアント、キャッシュが失われた状態でも同じ値になるとは限りません。

計算・日本語抽出・論理問題の基本動作

速度測定とは別に、次の3問を各モデルに与えました。

テスト 問題の要点 期待したJSON
計算 17×24 {"answer":408}
日本語抽出 「会議は2026年10月18日、東京で開催。参加者は12人。」から抽出 {"date":"2026-10-18","city":"東京","participants":12}
論理 琥珀色の箱はすべて重く、重い箱は棚Aにない。琥珀色の箱を棚Aに置けるか {"possible":false}

いずれもJSONだけを返すよう指示しました。全モデルで内容は正解でしたが、Qwen3.6-35B-A3Bの日本語抽出回答にはMarkdownコードフェンスが付いていました。

モデル 内容一致 応答全体がそのままJSONとして解析可能
Qwen3.6-35B-A3B 3/3 2/3
Qwen3.6-27B 3/3 3/3
Bolt 3/3 3/3
Super VL 3/3 3/3

「内容一致」はコードフェンスを除去して正解JSONと照合した結果です。3問だけの基本動作確認なので、推論能力や日本語能力全体の優劣を評価するものではありません。

テキスト推論時のメモリ

画像エンコーダーをロードしない比較測定中の値です。画像・動画用の測定とはリクエスト数や状態が異なります。

モデル プロセスRSSピーク GTT最大 MemAvailable最小
Qwen3.6-35B-A3B 1.96 GiB 21.00 GiB 63.15 GiB
Qwen3.6-27B 3.87 GiB 26.47 GiB 55.70 GiB
Bolt 3.67 GiB 20.68 GiB 61.40 GiB
Super VL 3.69 GiB 59.27 GiB 23.07 GiB

ここでもRSSとGTTを合算してはいけません。今回のSuper VLは画像用サーバーでもテキスト専用でも実行できましたが、同じ96 GB構成で任意の画像枚数やコンテキスト長まで収まるという保証ではありません。

今回確認できた範囲

Radeon 8060Sとllama.cppのHIPバックエンドで、Super VLのAD-IQ3_XXSを全層GPUオフロードし、画像エンコーダーもGPUで実行できました。テキスト生成は約19.2 tokens/sで、合成静止画の認識と、短い動画のフレーム列・MP4入力も動作しました。

一方、動画では存在しない斜め移動の付加と、出現時刻の誤認識がありました。時刻と画像の対応を明示すると正答した例はありますが、これだけで実動画の時刻精度を保証することはできません。

残る検証は、自然画像・実動画の品質、長時間入力、解像度やフレーム数を増やした際のメモリ、長期運転の安定性です。テキスト比較も反復した合成長文を使い、モデル順を固定した3回の逐次測定なので、異なる入力や並列負荷、電力状態で結果は変わります。過去の別ビルドでの測定値とは混ぜず、この記事の共通条件での結果として扱っています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?