Chuyển đến nội dung chính

レッスン 9: ビジョン モデル - クラウドを使用しない画像解析

Apple Silicon 上で LLaVA、Gemma 3 Vision、Qwen VL を実行します。画像分析、テキスト読み取り、OCR、説明 – すべてオフライン。高いパフォーマンスを実現するために mlx-vlm を統合します。

🧠 AI と ML — レッスン 2 レッスン 9: ビジョン モデル - 画像解析 クラウドは必要ありません

Apple Silicon で Ollama を使用して AI Local を実行する

パート 3: API 統合とアプリケーション プログラミング

xdev.asia

はじめに

ビジョン モデル (VLM - ビジョン言語モデル) は、画像を「見て」理解することができます。 Apple Silicon と Ollama のおかげで、完全にローカルで実行できるため、機密性の高い写真をクラウドに送信する必要がありません。


1. Ollama のビジョン モデル

人気モデル

モデルサイズ必要なRAM特長
llava:7b4.7GB8GB最初の VLM モデル、安定
llava:13b8.0GB12GBより正確に
llava-llama35.5GB8GBラマ 3 に基づく
gemma3:4b3.3GB6GB軽くて速く、視覚をサポート
gemma3:12b8.1GB12GBバランスが良い
gemma3:27b17GB24GB最高品質
qwen2.5-vl:7b5.3GB10GBテキスト/ドキュメントに優れています
minicpm-v5.5GB8GBコンパクトで強力なOCR

プルモデル

# Khuyến nghị cho MacBook 16GB RAM
ollama pull gemma3:12b

# Cho MacBook 8GB RAM
ollama pull gemma3:4b

# Model OCR chuyên dụng
ollama pull minicpm-v

2. CLIから使用する

写真の説明

# Mô tả ảnh
ollama run gemma3:12b "Describe this image in detail" ./screenshot.png

# Tiếng Việt
ollama run gemma3:12b "Mô tả chi tiết hình ảnh này" ./photo.jpg

たくさんの写真

ollama run gemma3:12b "So sánh 2 bức ảnh này" ./before.png ./after.png

3. Python: 画像解析

Ollama ライブラリの基本

import ollama

response = ollama.chat(
    model='gemma3:12b',
    messages=[{
        'role': 'user',
        'content': 'Mô tả chi tiết hình ảnh này bằng tiếng Việt',
        'images': ['./screenshot.png']
    }]
)

print(response['message']['content'])

Base64 を使用する

import ollama
import base64

def analyze_image(image_path, prompt="Mô tả hình ảnh này"):
    with open(image_path, 'rb') as f:
        image_data = base64.b64encode(f.read()).decode('utf-8')

    response = ollama.chat(
        model='gemma3:12b',
        messages=[{
            'role': 'user',
            'content': prompt,
            'images': [image_data]
        }]
    )
    return response['message']['content']

# Sử dụng
result = analyze_image("diagram.png", "Giải thích architecture diagram này")
print(result)

API を直接使用する

import requests
import base64

def vision_api(image_path, prompt):
    with open(image_path, 'rb') as f:
        image_b64 = base64.b64encode(f.read()).decode('utf-8')

    response = requests.post(
        'http://localhost:11434/api/chat',
        json={
            'model': 'gemma3:12b',
            'messages': [{
                'role': 'user',
                'content': prompt,
                'images': [image_b64]
            }],
            'stream': False
        }
    )
    return response.json()['message']['content']

result = vision_api("error.png", "Đọc error message trong screenshot này")
print(result)

4. 実際の使用例

###4.1. OCR — 画像からテキストを読み取る

import ollama

def ocr_image(image_path):
    response = ollama.chat(
        model='minicpm-v',  # Tốt cho OCR
        messages=[{
            'role': 'user',
            'content': '''Đọc và trích xuất toàn bộ text trong hình ảnh này.
Giữ nguyên format, xuống dòng đúng vị trí.
Chỉ trả về text, không thêm giải thích.''',
            'images': [image_path]
        }]
    )
    return response['message']['content']

text = ocr_image("invoice.jpg")
print(text)

###4.2.スクリーンショットからコードを分析する

def analyze_code_screenshot(image_path):
    response = ollama.chat(
        model='gemma3:12b',
        messages=[{
            'role': 'user',
            'content': '''Phân tích screenshot code này:
1. Đọc code trong hình
2. Giải thích code làm gì
3. Tìm bugs hoặc issues (nếu có)
4. Đề xuất cải thiện

Trả lời bằng tiếng Việt.''',
            'images': [image_path]
        }]
    )
    return response['message']['content']

result = analyze_code_screenshot("code_review.png")
print(result)

###4.3. UI/UXの説明

def analyze_ui(image_path):
    response = ollama.chat(
        model='gemma3:12b',
        messages=[{
            'role': 'user',
            'content': '''Phân tích thiết kế UI này:
1. Layout và bố cục
2. Color scheme
3. Typography
4. UX issues (nếu có)
5. Đề xuất cải thiện

Trả lời theo format markdown.''',
            'images': [image_path]
        }]
    )
    return response['message']['content']

###4.4.複数画像の一括処理

import ollama
from pathlib import Path

def batch_analyze(folder_path, prompt="Mô tả hình ảnh"):
    image_dir = Path(folder_path)
    extensions = {'.jpg', '.jpeg', '.png', '.webp', '.gif'}

    results = {}
    for img_file in sorted(image_dir.iterdir()):
        if img_file.suffix.lower() in extensions:
            print(f"📷 Đang phân tích: {img_file.name}...")
            response = ollama.chat(
                model='gemma3:4b',  # Dùng model nhẹ cho batch
                messages=[{
                    'role': 'user',
                    'content': prompt,
                    'images': [str(img_file)]
                }]
            )
            results[img_file.name] = response['message']['content']
            print(f"   ✅ Done\n")

    return results

# Phân tích tất cả ảnh trong folder
results = batch_analyze(
    "./screenshots",
    "Đây là screenshot lỗi. Tóm tắt error message trong 1-2 câu."
)

for filename, analysis in results.items():
    print(f"📄 {filename}: {analysis}\n")

5. Vision モデルのパフォーマンスを比較する

MacBook Pro M3 Pro 18GB RAM でのベンチマーク:

モデル応答時間品質説明OCR 精度
gemma3:4b~3秒⭐⭐⭐⭐⭐⭐
gemma3:12b~8秒⭐⭐⭐⭐⭐⭐⭐⭐
llava:7b~5秒⭐⭐⭐⭐⭐
minicpm-v~6秒⭐⭐⭐⭐⭐⭐⭐⭐
qwen2.5-vl:7b~7秒⭐⭐⭐⭐⭐⭐⭐⭐

スクリプトのベンチマーク

import ollama
import time

MODELS = ['gemma3:4b', 'gemma3:12b', 'llava:7b']
TEST_IMAGE = './test.png'
PROMPT = 'Describe this image in detail'

for model in MODELS:
    print(f"\n--- {model} ---")
    start = time.time()
    response = ollama.chat(
        model=model,
        messages=[{
            'role': 'user',
            'content': PROMPT,
            'images': [TEST_IMAGE]
        }]
    )
    elapsed = time.time() - start
    content = response['message']['content']
    print(f"⏱️  Time: {elapsed:.1f}s")
    print(f"📝 Length: {len(content)} chars")
    print(f"💬 {content[:200]}...")

6. mlx-vlm — MLX を使用して Vision モデルを実行する

より高いパフォーマンス (バッチ処理、カスタム パイプライン) が必要な場合は、次を使用します。 mlx-vlm:

pip3 install mlx-vlm
from mlx_vlm import load, generate

# Load model
model, processor = load("mlx-community/Qwen2.5-VL-7B-Instruct-4bit")

# Generate
output = generate(
    model,
    processor,
    "Describe this image",
    ["./photo.jpg"],
    max_tokens=500,
    verbose=False,
)
print(output)

Ollama と mlx-vlm を比較します。

オラマmlx-vlm
セットアップ簡単、引っ張って実行pip インストール、コードが必要です
APIレスト、CLIPython のみ
速度良い~20% 高速
モデル多くのオプション少ない
バッチ各写真バッチサポート
使用例一般生産パイプライン

7. プライバシーとセキュリティ

ローカルのビジョン モデルは、多くのセキュリティ問題を解決します。

  • 医療画像: X 線および CT スキャン分析をクラウドに送信する必要はありません
  • 機密文書: OCR契約書、社内請求書
  • スクリーンショット コード: ソース コードを公開せずにレビューします
  • カメラ フィード: ローカル監視ビデオ/写真を処理します
# Ví dụ: xử lý tài liệu nội bộ
def process_confidential_doc(image_path):
    """Trích xuất thông tin từ tài liệu mật - hoàn toàn offline."""
    response = ollama.chat(
        model='minicpm-v',
        messages=[{
            'role': 'user',
            'content': '''Trích xuất thông tin từ tài liệu:
- Ngày tháng
- Tên người/tổ chức
- Số tiền (nếu có)
- Nội dung chính

Format JSON.''',
            'images': [image_path]
        }]
    )
    return response['message']['content']

概要

特長おすすめモデル|
一般的な写真の説明gemma3:12b
OCR / テキスト読み取りminicpm-v
軽くて速いgemma3:4b
文書を分析するqwen2.5-vl:7b
コードのスクリーンショットgemma3:12b
バッチ処理mlx-vlm + 4bitモデル

演習

1.プルモデル gemma3:4b 5 つの異なる写真について説明します 2.書籍ページの写真からテキストを読み取る OCR スクリプトを構築する 3. バッチエラーのスクリーンショットを分析するツールを作成します (5 枚以上の画像) 4. OCR 結果を比較します。 minicpm-v そして gemma3:12b 5. (おまけ) OpenCV + Ollama ビジョンを使用して Web カメラからの画像をリアルタイムに処理する

次の記事: パフォーマンスの最適化 — RAM、コンテキスト、同時実行 →