Qwen-VL 계열과 Dynamic-FPS 비디오
Qwen-VL 계열, 즉 Qwen-VL(2023), Qwen2-VL(2024), Qwen2.5-VL(2025), Qwen3-VL(2025)은 2026년 기준 가장 영향력 있는 오픈 비전-언어 모델(open vision-language model) 계보입니다. 각 세대는 결정적인 아키텍처(architecture) 선택을 하나씩 내렸고, 오픈 생태계는 그 선택을 대개 12개월 안에 그대로 받아들였습니다. 그 결정적 선택은 다음 네 가지입니다. M-RoPE 기반 네이티브 동적 해상도(native dynamic resolution), 절대 시간 정렬(absolute time alignment)을 갖춘 동적 FPS 샘플링(dynamic-FPS sampling), 비전 트랜스포머(ViT)의 윈도우 어텐션(window attention), 그리고 구조화된 에이전트 출력 포맷(structured agent output format)입니다. Qwen3-VL에 이르러 레시피(recipe)는 안정화되었습니다. 네이티브 종횡비(native-aspect-ratio) 입력을 받는 2D-RoPE-ViT 인코더(encoder), 대형 Qwen3 언어 모델 기반(language base)으로 이어지는 MLP 프로젝터(projector), 그리고 OCR, 그라운딩(grounding), 에이전트 행동(agent behavior)을 일급 목표로 강조하는 학습 단계가 그 구성입니다. 이 강의는 Qwen-VL 계열을 시간 순서로 읽어 내려가며, 왜 각 설계 노브(knob)가 지금 위치에 있는지를 이해하도록 돕습니다.
유형: Learn
언어: Python (표준 라이브러리, M-RoPE 인코더 + 동적 FPS 샘플러)
선수 지식: Phase 12 · 06 (patch-n'-pack)
예상 시간: 약 120분
학습 목표
- M-RoPE의 세 축 회전(rotation), 즉 시간(temporal), 높이(height), 너비(width) 회전을 계산하고 세 축이 모두 필요한 이유를 설명합니다.
- 비디오에 맞는 동적 FPS 샘플링 전략(dynamic-FPS sampling strategy)을 고르고, 초당 토큰 수(tokens-per-second)와 이벤트 검출 정확도(event-detection accuracy)의 트레이드오프(tradeoff)를 설명합니다.
- Qwen-VL의 네 세대 업그레이드를 순서대로 말하고, 각 업그레이드가 무엇을 가능하게 했는지 설명합니다.
- Qwen2.5-VL 스타일의 JSON 에이전트 출력 포맷을 연결하고, VLM 응답(response)에서 구조화된 도구 호출(structured tool call)을 파싱(parse)합니다.
문제
Qwen-VL은 2023년 8월에 LLaVA-1.5와 BLIP-2에 대한 직접적인 응답으로 출시되었습니다. Qwen 팀이 겨냥한 빈틈은 세 가지였습니다. 해상도(resolution), 비디오(video), 그리고 구조화된 출력(structured output)입니다.
해상도: LLaVA-1.5는 336x336에서 동작했습니다. 일반적인 사진에는 괜찮지만, 중국어 송장(invoice)이나 빽빽한 스프레드시트 스크린샷에는 거의 쓸모가 없습니다. Qwen-VL의 첫 번째 혁신은 448x448 해상도와, 좌표를 갖춘 바운딩 박스 출력(grounded bounding-box output)이었습니다. 모델이 대상의 위치를 직접 가리킬 수 있게 된 것입니다.
비디오: Video-LLaMA는 프레임별 인코더를 쌓아 LLM에 그대로 흘려보냈습니다. 짧은 클립(clip)에는 통했지만, 시간 축 자체가 신호인 수 분 길이의 비디오에는 적합하지 않았습니다. Qwen 팀은 시간을 이해하는 단일 인코더를 원했습니다.
구조화된 출력: LLaVA는 자유 형식(free-form) 텍스트만 출력했습니다. 에이전트(agent)에는 JSON이 필요합니다. Qwen-VL은 바운딩 박스 좌표를 텍스트로 포함하는 명시적인 JSON 출력 포맷으로 학습했습니다.
Qwen-VL의 모든 세대는 이 세 축 중 하나를 확장합니다.
개념
Qwen-VL (2023년 8월)
첫 세대는 OpenCLIP ViT-bigG/14 인코더(파라미터 2.5B), Llama 호환 Q-Former(쿼리(query) 256개를 사용하는 1-단계), Qwen-7B 기반으로 구성되었습니다. 기여는 다음과 같습니다.
- 448x448 해상도입니다. 당시 오픈 VLM 기준 SOTA였습니다.
- 그라운딩(grounding)입니다. 명시적인 좌표 토큰 출력(coordinate-token output)을 포함한 이미지-텍스트 쌍(image-text pair)으로 학습했습니다. 예:
"The cat is at <box>(112, 204), (280, 344)</box>".
- 처음부터 중국어 + 영어 다국어(multilingual) 학습을 채택했습니다.
당시 벤치마크에서 영어로는 GPT-4V와 견줄 수준이었고, 중국어에서는 우세했습니다. 진짜 주목할 만한 점은 그라운딩 지도학습(grounding supervision)이었습니다.
Qwen2-VL (2024년 9월) — M-RoPE와 네이티브 해상도
Qwen2-VL은 고정 해상도(fixed-resolution) + Q-Former 구조를 네이티브 동적 해상도(native dynamic-resolution) ViT 인코더로 바꾸었습니다. 핵심 변화는 다음과 같습니다.
- 네이티브 동적 해상도. ViT는 28로 나누어떨어지는 임의의 HxW를 받습니다. 패치(patch) 14에 2x 공간 병합(spatial merge)을 적용합니다. 1120x672 이미지(병합된 패치 40x24)는 시각 토큰(visual token) 960개를 만들어 냅니다. 리사이즈(resize)도, 타일링(tiling)도, 썸네일도 없습니다.
- M-RoPE(Multimodal RoPE). 각 토큰은 1D 위치가 아니라 3D 위치
(t, h, w)를 가집니다. 이미지에서는 t=0이고, 비디오에서는 t=frame_index입니다. RoPE는 축마다 다른 주파수(frequency)로 쿼리/키 벡터(query/key vector)를 회전시킵니다. 별도의 위치 임베딩 테이블(positional embedding table)은 두지 않습니다.
- MLP 프로젝터. Q-Former를 제거하고, 병합된 패치 토큰 위에 2-층(layer) MLP를 둡니다.
- 동적 FPS(dynamic FPS)를 갖춘 비디오. 기본적으로 1-2 FPS로 샘플링하지만, 모델은 임의의 프레임 수를 받을 수 있습니다.
결과적으로 Qwen2-VL-7B는 여러 멀티모달(multimodal) 벤치마크에서 GPT-4o와 비슷한 수준에 도달했고, DocVQA에서는 GPT-4o를 앞섰습니다(94.5 vs 88.4). 결정적인 변화는 아키텍처였습니다.
Qwen2.5-VL (2025년 2월) — 동적 FPS + 절대 시간
Qwen2.5-VL의 큰 변화는 비디오에 있었습니다. 동적 FPS는 단순히 "필요할 때 프레임을 더 많이 샘플링한다"는 의미가 아닙니다. 논문은 다음을 정식화했습니다.
- 절대 시간 토큰(absolute time token). 위치 인덱스(frame 0, 1, 2…) 대신 실제 타임스탬프(timestamp)를 사용합니다. 예:
"At 0:04, the cat jumps." 모델은 프레임 토큰 사이에 끼워 넣은 <time>0.04</time> 토큰을 보게 됩니다.
- 동적 FPS. 느린 영상에는 1 FPS, 액션이 많은 영상에는 4 FPS 이상을 사용합니다. 사용자가 직접 고르거나 학습자(trainer)가 정하며, M-RoPE가 거기에 맞춰 적응합니다.
- ViT의 윈도우 어텐션(window attention). 처리량(throughput)을 위해 공간 어텐션(spatial attention)은 블록 내부의 윈도우 단위 지역 어텐션(local attention)으로 수행하고, 몇 층마다 전역 어텐션(global attention)을 끼워 넣습니다.
- 명시적인 JSON 출력 포맷. 도구 호출(tool-call) 데이터로 학습합니다. 예:
{"tool": "click", "coords": [380, 220]}. 곧바로 에이전트로 쓸 수 있는(agent-ready) 상태입니다.
- MRoPE-v2 스케일링(scaling). 위치는 최대 입력 크기에 맞춰 스케일링되므로, 10분짜리 비디오에서도 주파수 범위(frequency range)가 고갈되지 않습니다.
벤치마크에서는 Qwen2.5-VL-72B가 대부분의 비디오 벤치마크에서 GPT-4o를 앞섰고, 문서에서는 Gemini 2.0과 비슷한 수준이었으며, GUI 그라운딩에서는 오픈 모델 SOTA를 세웠습니다. ScreenSpot 정확도는 Qwen2-VL의 55%에서 Qwen2.5-VL의 84%로 뛰어올랐고, GPT-4o의 38%보다 훨씬 높았습니다.
Qwen3-VL (2025년 11월)
Qwen3-VL은 새로 발명한다기보다는 기존 구조를 통합하는 점진적(incremental) 업그레이드에 가깝습니다. 더 큰 LLM 백본(backbone)인 Qwen3-72B, 확장된 학습 데이터, 개선된 OCR, Qwen3의 "사고 모드(thinking mode)"를 통한 더 강한 추론을 사용합니다. ViT와 M-RoPE는 그대로 유지됩니다. 논문은 아키텍처보다 데이터와 학습 개선에 초점을 맞춥니다.
계보가 전하는 시사점은 분명합니다. 2025년이 되면 Qwen-VL 아키텍처는 안정화되었습니다. 이후 세대는 기본 구성 요소(primitive)를 바꾸기보다 연산량(compute)과 데이터를 키우는 방향으로 갑니다.
M-RoPE 수식
고전적인 RoPE는 차원(dimension) d인 쿼리 q를 위치 m에 따라 쌍으로 묶인 좌표(paired coordinate)로 회전시킵니다.
q_rot[2i] = q[2i] * cos(m * theta_i) - q[2i+1] * sin(m * theta_i)
q_rot[2i+1] = q[2i] * sin(m * theta_i) + q[2i+1] * cos(m * theta_i)
theta_i = 10000^(-2i/d)
M-RoPE는 은닉 차원(hidden dim)을 세 개의 밴드(band)로 나눕니다. 예를 들어 d = 96이라면 시간 축에 32 차원, 높이 축에 32 차원, 너비 축에 32 차원을 할당합니다. 각 밴드는 자기 축 위치로 회전합니다. (t=5, h=10, w=20) 위치의 패치는 세 밴드에 각각 R_t(5), R_h(10), R_w(20) 회전을 적용받습니다.
텍스트 토큰은 t = text_index, h = 0, w = 0을 쓰거나, 정규화된 값(normalized choice)을 써서 호환성을 유지합니다. 비디오 프레임은 t = frame_time, h = row, w = col을 씁니다. 단일 이미지는 t = 0을 씁니다.
이 방식의 장점은, 하나의 위치 인코딩이 텍스트, 이미지, 비디오를 분기 코드(branch code)나 별도의 위치 테이블 없이 모두 처리한다는 점입니다.
동적 FPS 샘플링 로직
길이가 T초인 비디오와 목표 토큰 예산(target-token budget) B가 주어졌다고 합시다.
- 감당 가능한 최대 FPS를 계산합니다.
fps_max = B / (T * tokens_per_frame)입니다.
{1, 2, 4, 8} 가운데 fps <= fps_max를 만족하는 목표 FPS를 고릅니다.
- 움직임이 많으면 광학 흐름(optical-flow) 휴리스틱이나 사용자의 명시적 요청에 따라 더 높은 FPS를 고릅니다. 움직임이 적으면 더 낮게 고릅니다.
- 선택한 FPS로 균일하게(uniform) 샘플링하고, 프레임 사이에
<time>t</time> 토큰을 삽입합니다.
Qwen2.5-VL은 이 로직을 암묵적으로(implicit) 학습합니다. 추론(inference) 시에는 사용자가 fps 파라미터(parameter)로 제어합니다. 60초짜리 액션 시퀀스를 4 FPS에, 프레임당 81 토큰으로 처리하면 19440 토큰이 됩니다. 32k 컨텍스트(context) 안에서 충분히 다룰 수 있는 양입니다.
구조화된 에이전트 출력
Qwen2.5-VL의 에이전트 학습은 구조화된 도구 호출(structured tool call)을 명시적인 목표로 삼습니다.
{
"tool": "mouse_click",
"coords": [1024, 512],
"button": "left",
"modifier": null
}
파싱은 결정적(deterministic)입니다. 모델 출력에 JSON.parse만 적용하면 됩니다. 자유 형식의 "click at (1024, 512)"와 비교해 보세요. 자유 형식은 정규식(regex)과 모호성 처리(ambiguity handling)가 필요합니다. 이 변화가 바로 Qwen2.5-VL의 ScreenSpot 점수가 Qwen2-VL의 55%에서 84%로 뛰어오른 이유입니다.
사용해보기
code/main.py는 다음을 구현합니다.
- 텍스트, 이미지 패치, 비디오 프레임이 섞인 패킹된 시퀀스(packed sequence)에 대한 M-RoPE 위치 계산입니다.
- 동적 FPS 샘플러입니다.
(duration, budget, motion_level)이 주어지면 FPS를 고르고, 프레임 타임스탬프(frame timestamp)를 출력합니다.
- 좌표 필드가 들어 있는 도구 호출 응답을 처리하는 토이(toy) Qwen2.5-VL JSON 출력 파서(parser)입니다.
직접 실행한 뒤, 5분짜리 비디오에서 고정 FPS(fixed-FPS)를 동적 FPS로 바꿨을 때 어떤 차이가 나는지 직접 느껴 보세요.
산출물 만들기
이 강의는 outputs/skill-qwen-vl-pipeline-designer.md를 만들어 냅니다. 비디오 과제(모니터링, 에이전트, 동작 인식(action recognition), 접근성(accessibility))가 주어지면 Qwen2.5-VL 설정(configuration)을 출력합니다. 여기에는 프레임 예산(frame budget), FPS 전략, 윈도우 어텐션 플래그(flag), 에이전트 출력 모드(agent-output mode), 그리고 지연 시간 추정치(latency estimate)가 포함됩니다. 비디오 제품에 Qwen-VL 계열 모델을 배포할 때마다 사용합니다.
연습문제
-
쉬움: 은닉 48, 밴드당 16 차원, 기준 theta(base theta) 10000일 때 (t=3, h=5, w=7) 패치의 M-RoPE 회전을 계산합니다. 각 밴드의 처음 세 쌍에 대한 회전 각도를 보입니다.
-
중간: 10분짜리 보안 카메라 녹화 영상을 1 FPS로 처리하면 몇 프레임이 나옵니까? 해상도 384에 3x 풀링(pool)을 적용하면 전체 토큰은 몇 개입니까? Qwen2.5-VL의 기본 32k 컨텍스트가 이를 처리할 수 있습니까?
-
중간: 30초짜리 테니스 랠리(tennis rally), 30초짜리 요리 시연 영상(recipe demo), 30초짜리 UI 에이전트 녹화 영상 각각에 대해 FPS를 고릅니다. 동적 FPS 로직으로 그 선택을 정당화합니다.
-
어려움: Qwen2.5-VL은 Q-Former를 완전히 제거합니다. 왜 단순한 MLP가 2023년에는 충분하지 않았지만 2025년에는 동작할까요? 힌트는 데이터 규모(data scale)와 인코더 품질(encoder quality)입니다.
-
어려움: Qwen2.5-VL의 JSON 도구 호출 출력 세 개를 Python 딕셔너리(dict)로 파싱합니다. 깨진(malformed) JSON에서는 무엇이 실패하며, Qwen 쿡북(cookbook)은 어떤 복구 전략(recovery strategy)을 권장합니까?
핵심 용어
| 용어 | 흔한 설명 | 실제 의미 |
|---|
| M-RoPE | "Multimodal RoPE" | 은닉 차원 안에 시간, 높이, 너비 밴드를 두는 3D 회전 위치 임베딩(rotary position embedding)입니다. |
| Dynamic FPS | "Smart sampling" | 움직임, 영상 길이(duration), 토큰 예산에 따라 비디오마다 프레임 샘플링 속도를 고르는 방식입니다. |
| Absolute time token | "Timestamp token" | 모델이 프레임 인덱스가 아니라 실제 초 단위 시간을 보도록 시퀀스에 끼워 넣는 <time>t</time> 토큰입니다. |
| Window attention | "Local attention" | 속도를 위해 공간 자기 어텐션(spatial self-attention)을 작은 윈도우 안으로 제한하고, 주기적으로 전역 어텐션을 더하는 방식입니다. |
| Structured agent output | "JSON mode" | VLM이 좌표와 도구 이름을 포함한 파싱 가능한 JSON을 출력하도록 학습 데이터로 지도하는 방식입니다. |
| min_pixels / max_pixels | "Resolution bounds" | 전체 픽셀 수를, 따라서 토큰 수를 제한하는 Qwen2.5-VL의 요청별(per-request) 제어 옵션입니다. |
| Grounding | "Point-at-it" | 바운딩 박스 좌표를 텍스트 토큰으로 출력하는 능력입니다. Qwen-VL v1부터 사용되어 왔습니다. |
더 읽을거리