EN Last sync: 2026-01-15

第3章: マルチモーダル生成

テキストから画像、動画理解、Any-to-Anyモデル

読了時間: 35-40分 コード例: 10 演習: 4

3.1 テキストから画像生成

テキストから画像モデルは、自然言語の説明から画像を生成します。この機能はクリエイティブワークフローを変革し、ビジュアルコンテンツ作成を民主化しました。

主要なテキストから画像モデル(2025年)

モデル 強み 制限 最適な用途
DALL-E 3 プロンプト精度、テキストレンダリング 芸術的スタイル化が弱い マーケティング、プロダクトデザイン
Midjourney v6 芸術的品質、美的センス 画像内テキストが弱い コンセプトアート、クリエイティブワーク
Stable Diffusion XL オープンソース、カスタマイズ可能 学習曲線が急 カスタムファインチューニング、研究
Janus-Pro 統一モデル、MITライセンス 新しい、エコシステムが小さい オープンソースプロジェクト

拡散モデル: 基盤技術

現代のテキストから画像モデルは拡散を使用します。これは画像へのノイズの段階的な追加を逆転することを学習するプロセスです。

graph LR subgraph Forward["順方向プロセス(学習)"] X0[クリーン画像 x₀] --> |ノイズ追加| X1[x₁] X1 --> |ノイズ追加| X2[x₂] X2 --> |...| XT[純粋ノイズ xₜ] end subgraph Reverse["逆方向プロセス(生成)"] NT[ランダムノイズ] --> |ノイズ除去| N1[部分的にノイズ除去] N1 --> |ノイズ除去| N2[...] N2 --> |ノイズ除去| IMG[生成画像] end TXT[テキストプロンプト] --> |条件付け| N1 style TXT fill:#9b59b6,color:white

拡散プロセス

順方向: 訓練画像にガウシアンノイズを徐々に追加

$$q(x_t | x_{t-1}) = \mathcal{N}(x_t; \sqrt{1-\beta_t}x_{t-1}, \beta_t \mathbf{I})$$

逆方向: テキストで条件付けしてノイズを予測・除去することを学習

$$p_\theta(x_{t-1} | x_t, c) = \mathcal{N}(x_{t-1}; \mu_\theta(x_t, t, c), \Sigma_\theta(x_t, t, c))$$

潜在拡散(Stable Diffusionアーキテクチャ)

graph TB subgraph Encoding IMG1[画像 512x512] --> VAE_E[VAEエンコーダー] VAE_E --> LAT[潜在 64x64x4] end subgraph Diffusion["潜在空間での拡散"] LAT --> UNET[U-Netノイズ除去器] TXT2[テキストプロンプト] --> CLIP2[CLIPテキストエンコーダー] CLIP2 --> COND[テキスト条件付け] COND --> UNET UNET --> LAT2[ノイズ除去された潜在] end subgraph Decoding LAT2 --> VAE_D[VAEデコーダー] VAE_D --> OUT[生成画像] end style UNET fill:#9b59b6,color:white style COND fill:#e3f2fd

Stable Diffusionでの画像生成

# Stable Diffusionによるテキストから画像
from diffusers import StableDiffusionPipeline
import torch

# モデルの読み込み
pipe = StableDiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    torch_dtype=torch.float16,
    variant="fp16"
)
pipe = pipe.to("cuda")

# 画像の生成
prompt = "桜が咲く静かな日本庭園、鯉の池、\
          伝統的な木製の橋、朝霧、フォトリアリスティック、8k"

negative_prompt = "ぼやけた、低品質、歪んだ、醜い"

image = pipe(
    prompt=prompt,
    negative_prompt=negative_prompt,
    num_inference_steps=50,
    guidance_scale=7.5,
    height=1024,
    width=1024
).images[0]

image.save("japanese_garden.png")

DALL-E 3 APIの使用

# OpenAI API経由のDALL-E 3
import openai
from PIL import Image
import requests
from io import BytesIO

client = openai.OpenAI(api_key="your-api-key")

response = client.images.generate(
    model="dall-e-3",
    prompt="空飛ぶ車がある未来の東京の夜景、\
            日本語のネオンサイン、サイバーパンク美学",
    size="1024x1024",
    quality="hd",
    n=1
)

# 画像をダウンロードして表示
image_url = response.data[0].url
image_response = requests.get(image_url)
image = Image.open(BytesIO(image_response.content))
image.save("cyberpunk_tokyo.png")

# 修正されたプロンプトを取得(DALL-E 3はプロンプトを修正する場合がある)
print(f"修正されたプロンプト: {response.data[0].revised_prompt}")

3.2 動画理解モデル

動画理解は、画像理解に時間的推論を拡張します - シーンが時間とともにどのように変化するかを理解します。

動画理解の課題

動画トークン化戦略

graph TB subgraph Sparse["スパースサンプリング"] V1[動画] --> S1[N番目のフレームごとにサンプリング] S1 --> F1[フレーム 1, 5, 10, ...] end subgraph Dense["デンス + 時間的"] V2[動画] --> S2[全フレーム] S2 --> TE[時間エンコーダー] TE --> TT[時間トークン] end subgraph Hierarchical["階層的"] V3[動画] --> CL[クリップレベル特徴] CL --> VL[動画レベル集約] end style TE fill:#9b59b6,color:white
# 時間トークンによる動画理解
import torch
import torch.nn as nn
from transformers import CLIPProcessor, CLIPModel

class SimpleVideoEncoder(nn.Module):
    """フレームを処理し時間情報を追加して動画をエンコード"""

    def __init__(self, clip_model_name="openai/clip-vit-base-patch32"):
        super().__init__()
        self.clip = CLIPModel.from_pretrained(clip_model_name)
        self.clip_processor = CLIPProcessor.from_pretrained(clip_model_name)

        # 学習可能な時間位置埋め込み
        self.temporal_embed = nn.Embedding(100, 512)  # 最大100フレーム

        # 時間アテンション
        self.temporal_attn = nn.TransformerEncoder(
            nn.TransformerEncoderLayer(d_model=512, nhead=8, batch_first=True),
            num_layers=2
        )

    def forward(self, frames):
        """
        frames: PIL画像のリストまたはテンソル (B, T, C, H, W)
        """
        B, T = len(frames), len(frames[0])

        # CLIPでフレーム特徴を抽出
        frame_features = []
        for batch in frames:
            inputs = self.clip_processor(images=batch, return_tensors="pt")
            with torch.no_grad():
                features = self.clip.get_image_features(**inputs)
            frame_features.append(features)

        # スタック: (B, T, D)
        frame_features = torch.stack(frame_features)

        # 時間位置埋め込みを追加
        positions = torch.arange(T).unsqueeze(0).expand(B, -1)
        temporal_pos = self.temporal_embed(positions)
        frame_features = frame_features + temporal_pos

        # 時間アテンションを適用
        video_features = self.temporal_attn(frame_features)

        # 動画レベル表現にプール
        video_embedding = video_features.mean(dim=1)

        return video_embedding, video_features

最先端: Molmo 2(2025年)

AI2のMolmo 2は動画理解の現在の最前線を代表しています。

3.3 Any-to-Anyマルチモーダルモデル

「Any-to-Any」モデルは複数の入力モダリティを受け付け、複数の出力モダリティを生成できます。

graph TB subgraph Inputs TI[テキスト] II[画像] AI[音声] VI[動画] end subgraph Model["Any-to-Anyモデル"] UT[統一トークナイザー] TR[Transformer] DT[デコーダー/ジェネレーター] end subgraph Outputs TO[テキスト] IO[画像] AO[音声] end TI --> UT II --> UT AI --> UT VI --> UT UT --> TR TR --> DT DT --> TO DT --> IO DT --> AO style TR fill:#9b59b6,color:white

GPT-4V/4oの機能

# GPT-4o: マルチモーダル推論
import openai
import base64

client = openai.OpenAI()

def encode_image_to_base64(image_path):
    with open(image_path, "rb") as f:
        return base64.b64encode(f.read()).decode('utf-8')

# 複数の画像を一緒に分析
def compare_images(image_paths, question):
    content = [{"type": "text", "text": question}]

    for path in image_paths:
        content.append({
            "type": "image_url",
            "image_url": {
                "url": f"data:image/jpeg;base64,{encode_image_to_base64(path)}"
            }
        })

    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": content}],
        max_tokens=500
    )

    return response.choices[0].message.content

# 例: ビフォー/アフター画像を比較
result = compare_images(
    ["room_before.jpg", "room_after.jpg"],
    "この部屋にどんな変更が加えられましたか?具体的な違いを挙げてください。"
)
print(result)

DeepSeek Janus-Pro: オープンソース統一モデル

Janus-Pro(2025年1月)は統一された理解と生成を持つ画期的なオープンソースモデルです。

Janus-Proアーキテクチャ

# Janus-Proで理解と生成
from transformers import AutoModelForCausalLM, AutoProcessor
import torch

# Janus-Proの読み込み
model = AutoModelForCausalLM.from_pretrained(
    "deepseek-ai/Janus-Pro-7B",
    torch_dtype=torch.bfloat16,
    device_map="auto",
    trust_remote_code=True
)
processor = AutoProcessor.from_pretrained(
    "deepseek-ai/Janus-Pro-7B",
    trust_remote_code=True
)

# 画像理解
def understand_image(image_path, question):
    from PIL import Image
    image = Image.open(image_path)

    conversation = [
        {"role": "user", "content": [
            {"type": "image", "image": image},
            {"type": "text", "text": question}
        ]}
    ]

    inputs = processor(conversation, return_tensors="pt").to(model.device)
    outputs = model.generate(**inputs, max_new_tokens=256)
    return processor.decode(outputs[0], skip_special_tokens=True)

# 画像生成
def generate_image(prompt):
    inputs = processor(
        text=prompt,
        return_tensors="pt",
        mode="generation"
    ).to(model.device)

    outputs = model.generate(**inputs, max_new_tokens=1024)
    image = processor.decode_image(outputs)
    return image

# 使用例
answer = understand_image("chart.png", "このチャートはどのようなトレンドを示していますか?")
generated = generate_image("夕日に照らされた雄大な山岳風景")

3.4 音声-視覚モデル

音声-視覚モデルはスピーチ、サウンド、視覚情報を統合します。

応用

# 音声-視覚処理の例
import torch
import torchaudio
from transformers import Wav2Vec2Processor, Wav2Vec2Model

class AudioVisualEncoder(nn.Module):
    """音声と視覚特徴を組み合わせる"""

    def __init__(self, visual_dim=512, audio_dim=768, hidden_dim=512):
        super().__init__()

        # 音声エンコーダー(Wav2Vec2)
        self.audio_processor = Wav2Vec2Processor.from_pretrained(
            "facebook/wav2vec2-base"
        )
        self.audio_encoder = Wav2Vec2Model.from_pretrained(
            "facebook/wav2vec2-base"
        )

        # 射影層
        self.visual_proj = nn.Linear(visual_dim, hidden_dim)
        self.audio_proj = nn.Linear(audio_dim, hidden_dim)

        # クロスモーダルアテンション
        self.cross_attn = nn.MultiheadAttention(hidden_dim, num_heads=8)

        # 融合
        self.fusion = nn.Linear(hidden_dim * 2, hidden_dim)

    def forward(self, visual_features, audio_waveform, sample_rate=16000):
        # 音声を処理
        audio_inputs = self.audio_processor(
            audio_waveform,
            sampling_rate=sample_rate,
            return_tensors="pt"
        )
        audio_features = self.audio_encoder(**audio_inputs).last_hidden_state

        # 共通空間に射影
        visual_proj = self.visual_proj(visual_features)
        audio_proj = self.audio_proj(audio_features)

        # クロスモーダルアテンション(音声が視覚にクエリ)
        attended, _ = self.cross_attn(
            audio_proj.transpose(0, 1),
            visual_proj.transpose(0, 1),
            visual_proj.transpose(0, 1)
        )
        attended = attended.transpose(0, 1)

        # モダリティを融合
        combined = torch.cat([audio_proj, attended], dim=-1)
        fused = self.fusion(combined)

        return fused

3.5 実践的な考慮事項

適切なモデルの選択

タスク 推奨モデル 理由
マーケティングビジュアル DALL-E 3 最高のプロンプト精度、テキストレンダリング
アートコンセプト Midjourney 優れた美的品質
カスタム訓練 Stable Diffusion オープンソース、LoRAサポート
視覚的会話 GPT-4V/Claude 3 最高の推論能力
オープンソース統一 Janus-Pro MITライセンス、競争力のある品質

コストの考慮

画像生成のコストは大きく異なります。

3.6 まとめ

第3章の重要ポイント

演習

演習1: 画像用プロンプトエンジニアリング

DALL-EとStable Diffusionで同じコンセプトを生成してください。結果を比較し、プロンプトの修正が出力品質にどう影響するか分析してください。

演習2: 動画フレーム分析

動画からキーフレームを抽出し、GPT-4Vを使って何が起きているかを説明してください。次に、時間平均を実装して動画サマリーを作成してください。

演習3: モデル比較

視覚的QAタスクで、GPT-4V、Claude 3、Janus-Proからの応答を比較してください。各モデルの長所と短所を分析してください。

演習4: コスト最適化

品質要件と予算制約に基づいて画像生成リクエストを異なるモデルにルーティングするシステムを設計してください。