LLM

Microsoft Phi-4-reasoning-vision-15B 실전 가이드 — "언제 생각할지" 스스로 결정하는 경량 멀티모달 모델

cell-devlog 2026. 6. 15. 15:16
반응형

 

추론 모델의 가장 큰 비용 문제는 항상 생각한다는 것입니다. 간단한 이미지 캡션 하나에도 수천 개의 추론 토큰을 태웁니다. Phi-4-reasoning-vision-15B는 이 문제를 다르게 접근합니다. 생각이 필요한지 아닌지를 모델이 스스로 판단합니다.


핵심 아이디어 — THINK vs NOTHINK 자동 전환

Phi-4-reasoning-vision-15B의 가장 큰 차별점은 태스크 복잡도에 따라 추론 모드를 자동으로 전환한다는 것입니다. 대부분의 추론 모델은 thinking on/off를 사용자가 직접 설정하고 모델은 그 설정을 따릅니다. Phi-4-reasoning-vision은 설정 없이 스스로 결정합니다.

시스템 프롬프트에서 이 동작이 명시적으로 정의돼 있습니다. NOTHINK 모드는 태스크가 명확하고 사실적이며 낮은 복잡도이거나 반복적 추론 없이 즉각 답할 수 있을 때 쓰입니다. THINK 모드는 다단계 분석, 증거 종합, 모호성 해소, 공간·수학·논리 추론이 필요할 때 자동 활성화됩니다.

실전에서 이게 의미하는 건 명확합니다. 영수증 이미지에서 합계 금액을 읽는 요청 → NOTHINK, 빠른 응답. 복잡한 과학 다이어그램 분석이나 GUI 자동화 → THINK, 추론 체인 전개. 같은 모델에서 태스크에 따라 레이턴시와 토큰 소모가 자동으로 최적화됩니다.


아키텍처

Phi-4-reasoning-vision-15B는 Phi-4-Reasoning 언어 백본에 SigLIP-2 비전 인코더를 미드퓨전 방식으로 결합합니다. 비전 인코더가 이미지를 비주얼 토큰으로 변환하고, 그 토큰이 언어 모델 임베딩 공간으로 프로젝션된 뒤 사전학습된 언어 모델이 처리하는 구조입니다.

이미지 해상도 처리 방식도 중요합니다. Microsoft는 Dynamic S, Multi-crop, Multi-crop with S, Naflex(동적 해상도) 네 가지 방식을 ablation 테스트했고, SigLIP-2의 Naflex 변형인 동적 해상도 방식이 특히 고해상도 스크린샷이나 작은 UI 요소 인식에서 가장 좋은 결과를 냈습니다. GUI 자동화에 특히 강한 이유가 여기 있습니다.

학습 데이터 효율도 눈에 띕니다. Phi-4-reasoning-vision-15B는 멀티모달 데이터 약 2,000억 토큰으로 학습했습니다. 이는 Qwen 2.5 VL, Qwen 3 VL, Kimi-VL, Gemma 3 같은 경쟁 멀티모달 모델들이 쓴 1조 토큰 이상과 비교하면 5분의 1 수준입니다.


벤치마크 — 어디서 강하나

주요 벤치마크 결과는 다음과 같습니다. AI2D(과학 다이어그램) 84.8%, ChartQA 83.3%, MathVista Mini 75.2%, ScreenSpot v2(UI 요소 그라운딩) 88.2%, MMMU 54.3%, OCRBench 76.0%입니다.

ScreenSpot v2에서 88.2%는 전작 Phi-4-mm-instruct의 28.5%에서 3배 이상 뛰어오른 수치입니다. 화면 위의 버튼, 메뉴, 텍스트 필드 같은 미세 인터랙티브 요소를 정확히 찾아내는 능력이 획기적으로 개선됐습니다.

MathVista_Mini에서는 Google Gemma-3-12b-it 대비 17% 높은 점수를 기록했습니다.


바로 쓰기 — Azure AI Foundry

가장 빠른 시작 방법은 Azure AI Foundry입니다. 가중치 다운로드나 GPU 인프라 없이 바로 엔드포인트를 배포할 수 있습니다.

Azure AI Foundry에서 배포 후 엔드포인트 URL과 API 키를 받아서 아래처럼 씁니다:

import requests
import base64

ENDPOINT = "https://YOUR-ENDPOINT.inference.ai.azure.com/v1/chat/completions"
API_KEY = "YOUR_AZURE_API_KEY"

def phi4_vision(image_path: str, prompt: str) -> str:
    with open(image_path, "rb") as f:
        image_b64 = base64.b64encode(f.read()).decode()

    ext = image_path.split(".")[-1].lower()
    mime = {"jpg": "image/jpeg", "jpeg": "image/jpeg",
            "png": "image/png", "webp": "image/webp"}.get(ext, "image/png")

    payload = {
        "model": "Phi-4-reasoning-vision-15B",
        "messages": [
            {
                "role": "system",
                "content": (
                    "You are Phi, a multimodal model trained by Microsoft. "
                    "Adapt your reasoning mode (NOTHINK vs THINK) automatically "
                    "based on the complexity of each task."
                )
            },
            {
                "role": "user",
                "content": [
                    {
                        "type": "image_url",
                        "image_url": {
                            "url": f"data:{mime};base64,{image_b64}"
                        }
                    },
                    {
                        "type": "text",
                        "text": prompt
                    }
                ]
            }
        ],
        "max_tokens": 2048
    }

    response = requests.post(
        ENDPOINT,
        headers={
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json"
        },
        json=payload
    )

    return response.json()["choices"][0]["message"]["content"]


# 사용 예시 1 — 차트 분석 (복잡 → THINK 모드 자동)
result = phi4_vision(
    "quarterly_revenue.png",
    "이 차트에서 분기별 성장률을 계산하고, 이상 값이 있다면 원인을 추론해줘."
)
print(result)

# 사용 예시 2 — 영수증 파싱 (단순 → NOTHINK 모드 자동)
result = phi4_vision(
    "receipt.jpg",
    "영수증에서 품목명, 수량, 금액을 JSON으로 추출해줘."
)
print(result)

Hugging Face Transformers로 로컬 실행

로컬 실행은 40GB 이상 VRAM GPU가 필요합니다. Hugging Face Transformers로 바로 돌릴 수 있습니다.

from transformers import AutoModelForCausalLM, AutoProcessor
from PIL import Image
import torch

model_id = "microsoft/Phi-4-reasoning-vision-15B"

processor = AutoProcessor.from_pretrained(
    model_id,
    trust_remote_code=True
)

model = AutoModelForCausalLM.from_pretrained(
    model_id,
    device_map="auto",
    torch_dtype=torch.bfloat16,
    trust_remote_code=True,
    attn_implementation="flash_attention_2"  # 속도 최적화
)

def run_phi4_vision(image_path: str, question: str) -> str:
    image = Image.open(image_path).convert("RGB")

    # 시스템 프롬프트 포함 — 공식 가이드 권장
    messages = [
        {
            "role": "system",
            "content": (
                "You are Phi, a multimodal model trained by Microsoft to help users. "
                "Adapt your reasoning mode (NOTHINK vs THINK) automatically based on "
                "the complexity, clarity, and confidence of each task."
            )
        },
        {
            "role": "user",
            "content": f"<|image_1|>\n{question}"
        }
    ]

    prompt = processor.tokenizer.apply_chat_template(
        messages,
        tokenize=False,
        add_generation_prompt=True
    )

    inputs = processor(prompt, [image], return_tensors="pt").to(model.device)

    with torch.no_grad():
        output = model.generate(
            **inputs,
            max_new_tokens=2048,
            temperature=0.1,
            do_sample=True
        )

    generated = output[0][inputs["input_ids"].shape[1]:]
    return processor.decode(generated, skip_special_tokens=True)


# 실행
result = run_phi4_vision(
    "diagram.png",
    "이 시스템 아키텍처 다이어그램의 데이터 흐름을 단계별로 설명하고, "
    "병목 지점이 될 수 있는 부분을 찾아줘."
)
print(result)

GUI 자동화 에이전트로 쓰기 — ScreenSpot v2 1위 활용

Phi-4-reasoning-vision-15B는 온라인 쇼핑 인터페이스처럼 실제 이커머스 화면에서 제품, 가격, 필터, 프로모션, 버튼, 카트 상태를 해석하고 에이전트가 액션을 선택할 수 있는 그라운딩 정보를 생성합니다.

스크린샷 기반 GUI 자동화 에이전트에 퍼셉션 레이어로 붙이는 패턴입니다:

import pyautogui
import time
from PIL import ImageGrab

def capture_and_analyze(instruction: str) -> dict:
    """
    현재 화면 캡처 → Phi-4-vision으로 UI 요소 분석 → 액션 좌표 반환
    """
    # 화면 캡처
    screenshot = ImageGrab.grab()
    screenshot.save("/tmp/screen.png")

    # Phi-4-vision으로 UI 파싱
    prompt = f"""
다음 작업을 수행하려면 어떤 UI 요소를 클릭해야 하나요?
작업: {instruction}

화면에서 해당 요소를 찾아 다음 JSON 형식으로 답해줘:
{{
  "element": "요소 설명",
  "action": "click | type | scroll",
  "coordinates": {{"x": 숫자, "y": 숫자}},
  "text_to_type": "타이핑할 텍스트 (해당시)"
}}
"""
    result = phi4_vision("/tmp/screen.png", prompt)

    import json
    try:
        return json.loads(result)
    except json.JSONDecodeError:
        return {"raw": result}

# 사용 예시: 브라우저 자동화
action = capture_and_analyze("검색창에 '파이썬 튜토리얼'을 입력하세요")

if action.get("action") == "click":
    pyautogui.click(action["coordinates"]["x"], action["coordinates"]["y"])
    time.sleep(0.5)

if action.get("action") == "type" and action.get("text_to_type"):
    pyautogui.click(action["coordinates"]["x"], action["coordinates"]["y"])
    pyautogui.typewrite(action["text_to_type"], interval=0.05)

vLLM으로 고처리량 배포

GPU 서버 환경이라면 vLLM으로 배포할 수 있습니다. 40GB 이상 VRAM이 필요합니다.

pip install vllm

vllm serve microsoft/Phi-4-reasoning-vision-15B \
  --max-model-len 16384 \
  --tensor-parallel-size 1 \
  --trust-remote-code \
  --dtype bfloat16

서빙 후 OpenAI 호환 엔드포인트(http://localhost:8000/v1)로 기존 코드 그대로 쓸 수 있습니다.


Nemotron 3 Nano Omni와 비교 — 어떻게 다른가

두 모델 모두 경량 멀티모달 추론 모델이지만 포지션이 다릅니다.

항목 Phi-4-reasoning-vision-15B Nemotron 3 Nano Omni

파라미터 15B (dense) 30B-A3B (MoE)
오디오 지원
영상 지원 ✅ (최대 2분)
GUI 자동화 ✅ ScreenSpot v2 88.2% ✅ OSWorld 47.4%
수학/과학 추론 ✅ 강점
VRAM 요구량 ~40GB ~36GB (FP8)
라이선스 MIT NVIDIA Open
추론 모드 자동 전환 ✅ THINK/NOTHINK

텍스트+이미지 처리, GUI 자동화, 수학·과학 추론 중심이면 Phi-4. 오디오·영상이 반드시 필요하거나 처리량 우선이면 Nemotron Omni가 맞습니다.


✅ 결론

  • 15B 경량이지만 수학·과학·GUI 자동화에서 훨씬 큰 모델과 경쟁합니다
  • THINK/NOTHINK 자동 전환이 핵심 — 레이턴시와 토큰 비용이 태스크에 맞게 자동 최적화됩니다
  • Azure AI Foundry에서 GPU 없이 바로 쓸 수 있습니다
  • ScreenSpot v2 88.2% — GUI 자동화 에이전트 퍼셉션 레이어로 실전 수준입니다
  • MIT 라이선스로 파인튜닝·상업 배포 모두 가능합니다

❌ 주의

  • 오디오·영상 입력은 지원하지 않습니다. 해당 모달리티가 필요하면 Nemotron Omni를 쓰세요
  • 추론 모드 자동 전환이 항상 정확하지는 않습니다. 복잡한 태스크에서 NOTHINK로 잘못 판단하면 명시적으로 <think> 태그를 프롬프트에 삽입해서 THINK 모드를 강제해야 합니다.
  • 로컬 실행 시 40GB VRAM 미만 환경에서는 양자화 필요 (공식 GGUF 미제공, 커뮤니티 의존)
  • 시스템 프롬프트 없이 실행하면 성능이 크게 떨어집니다. 반드시 공식 시스템 프롬프트를 포함하세요

 

반응형