멀티모달 생성

멀티모달 생성 (Multimodal Generation)

멀티모달(any-to-any) 모델은 텍스트, 이미지, 오디오, 비디오 등 다양한 유형의 입력 데이터를 처리하고 이러한 어떤 모달리티로도 출력을 생성할 수 있는 언어 모델입니다. 단일 시스템으로 텍스트-이미지 생성부터 오디오-텍스트 전사, 이미지 캡셔닝, 비디오 이해까지 폭넓은 작업을 처리할 수 있습니다.

출처: 문서

본문

기존의 단일 모달리티(unimodal) 또는 고정 모달리티 모델과 달리 입력과 출력의 유연한 조합을 허용합니다. 이 작업은 image-text-to-text와 많은 공통점이 있지만, 더 넓은 범위의 입력·출력 모달리티를 지원합니다.

이 가이드에서는 any-to-any 모델을 간략히 살펴보고, Transformers로 추론(inference)에 사용하는 방법을 보여드립니다. 보통 비전·언어 작업에 국한되는 Vision LLM과 달리, 옴니모달(omni-modal) 모델은 텍스트·이미지·오디오·비디오 등 어떤 조합의 모달리티를 입력으로 받아들이고, 텍스트나 이미지 같은 다른 모달리티로 출력을 생성할 수 있습니다.

먼저 의존성을 설치해 볼게요.

pip install -q transformers accelerate flash_attn

이제 모델과 프로세서를 초기화해 보겠습니다.

from transformers import AutoProcessor, AutoModelForMultimodalLM, infer_device
import torch

device = torch.device(infer_device())
model = AutoModelForMultimodalLM.from_pretrained(
    "Qwen/Qwen2.5-Omni-3B",
    dtype=torch.bfloat16,
    attn_implementation="flash_attention_2",
).to(device)

processor = AutoProcessor.from_pretrained("Qwen/Qwen2.5-Omni-3B")

이런 모델들은 보통 채팅 템플릿을 포함해 모달리티를 넘나드는 대화를 구조화합니다. 입력은 한 턴에 이미지, 텍스트, 오디오, 또는 기타 지원 형식을 섞을 수 있습니다. 출력도 설정에 따라 달라질 수 있습니다(예: 텍스트 생성 또는 오디오 생성).

다음은 "text + audio" 입력을 제공하고 텍스트 응답을 요청하는 예시입니다.

messages = [
    {
        "role": "user",
        "content": [
            {"type": "audio", "url": "https://huggingface.co/datasets/raushan-testing-hf/audio-test/resolve/main/f2641_0_throatclearing.wav"},
            {"type": "text", "text": "What do you hear in this audio?"},
        ]
    },
]

이제 프로세서의 apply_chat_template() 메서드를 호출해 이미지 입력과 함께 출력을 전처리하겠습니다.

inputs = processor.apply_chat_template(
    messages,
    tokenize=True,
    return_dict=True,
    return_tensors="pt",
    add_generation_prompt=True,
)

전처리된 입력을 모델에 전달할 수 있습니다.

with torch.no_grad():
    generated_ids = model.generate(**inputs, max_new_tokens=100)
generated_texts = processor.batch_decode(generated_ids, skip_special_tokens=True)
print(generated_texts)

Pipeline

가장 빠르게 시작하는 방법은 Pipeline API를 사용하는 것입니다. "any-to-any" 작업과 사용하려는 모델을 지정해 주세요.

from transformers import pipeline
pipe = pipeline("any-to-any", model="mistralai/Voxtral-Mini-3B-2507")

아래 예시는 채팅 템플릿으로 텍스트 입력을 형식화하고, 오디오를 멀티모달 데이터로 사용합니다.

messages = [
     {
         "role": "user",
         "content": [
             {
                 "type": "audio",
                 "url": "https://huggingface.co/datasets/raushan-testing-hf/audio-test/resolve/main/glass-breaking-151256.mp3",
             },
             {"type": "text", "text": "What do you hear in this audio?"},
         ],
     },
]

채팅 템플릿으로 형식화된 텍스트와 이미지를 Pipeline에 전달하고, return_full_text=False로 설정해 생성된 출력에서 입력을 제거합니다.

outputs = pipe(text=messages, max_new_tokens=20, return_full_text=False)
outputs[0]["generated_text"]

any-to-any pipeline은 any-to-any 모델로 오디오나 이미지를 생성하는 것도 지원합니다. 이를 위해서는 generation_mode 매개변수를 설정해야 합니다. 비디오 샘플링은 원하는 FPS로 설정하는 것을 잊지 마세요. 그렇지 않으면 샘플링 없이 전체 비디오가 로드됩니다. 다음은 예시 코드입니다.

import soundfile as sf
pipe = pipeline("any-to-any", model="Qwen/Qwen2.5-Omni-3B")
messages = [
    {
        "role": "user",
        "content": [
            {"type": "video", "path": "https://huggingface.co/datasets/raushan-testing-hf/videos-test/resolve/main/Cooking_cake.mp4"},
            {"type": "text", "text": "Describe this video."},
        ],
    },
]
output = pipe(text=messages, fps=1, load_audio_from_video=True, max_new_tokens=20, generation_mode="audio")
sf.write("generated_audio.wav", out[0]["generated_audio"])

더 알아보기 (Learn more)