Index
2026-04-13 — Progress

Graph-VLM QA 벤치마크 구축 및 전체 영상 평가

Graph-VLM | P01_01 27.5분 560-QA 벤치마크, 4단계 그래프 정규화 비교

TL;DR

67.9%
Graph Norm1
70.0%
Frame Baseline
75.0%
L4 Graph
560
QA 문항
535
Objects (Norm1)

1 배경 / 목적

Graph-VLM 파이프라인의 실질적 성능을 측정할 수 있는 공식 벤치마크가 없었음. 단순 VLM (프레임 샘플링)과 비교하여 그래프의 부가가치를 정량화하는 것이 목표. 특히 긴 영상에서 그래프가 장기 기억(L4), 시간 추론(EM3), 인과 추론(T3) 영역에서 이점을 보이는지 측정하고자 했음.

기존 한계: 1분 구간 테스트(80% vs 86.7%)만 있었고, 27.5분 전체 스케일에서의 검증이 없었음. async 빌드 스크립트도 구 API 사용으로 깨진 상태였음.

2 작업 내용

QA 생성 파이프라인 (src/qa_generator.py, scripts/generate_qa.py)

영상을 60초 구간으로 분할 → 각 구간을 VLM에 10프레임 샘플링해서 "상세 설명" 생성 → 구간 description 기반으로 카테고리×난이도 질문 생성. L1/L2는 구간 내, L3는 인접 구간 쌍, L4는 전체 요약. 타임스탬프/세그먼트 언급 문제 발견 → 프롬프트에 "이벤트 기반 질문만" 규칙 추가.

결과: P01_01 27.5분 전체 560개 QA L1(단일 장면): 181개 | L2(이벤트 내): 200개 L3(이벤트 간): 167개 | L4(장기 기억): 12개 비용: $0.24

Async 그래프 빌드 수정 (scripts/build_graph_async.py)

기존 sync 버전은 27.5분 분량에서 1.5시간 이상 걸려도 완료 불가. async 버전은 구 API(add_scene)를 사용하고 있어 깨진 상태였음 → 현재 구조(add_frame_description, keyframe/camera 지원)에 맞춰 수정. concurrent=10으로 30분에 완료.

결과 그래프: 1499 nodes (769 objects, 325 actions, 405 keyframes), 9693 edges 비용: $2.77 (1152 API calls) | 소요 시간: ~30분

VQA Pipeline MCQ 모드 (src/vqa_pipeline.py)

answer(question, choices=dict) 시그니처 추가. MCQ 프롬프트, regex letter 추출, None 방어 처리.

Post-processing 정규화 — Pass 1 (Regex)

769 object 노드 중 명백한 중복을 regex로 제거. prefix/suffix 제거 후 base name이 동일한 노드를 merge.

제거 prefix: chopped_, diced_, sliced_, wooden_, plastic_, metal_, glass_ 등 제거 suffix: _slices, _pieces, _01, _02, _left, _right 등 결과: 769 → 535 objects (234 merges)

Post-processing 정규화 — Pass 2 (VLM dedup)

535 objects를 카테고리별로 그룹화 → 80개씩 chunk → Gemini 2.0 Flash에 의미적 동일성 판단 요청. 11회 API 호출, $0.004. 235 merges → 535 → 300 objects.

문제: Pass 2가 너무 공격적 — 구분되어야 할 object들을 합쳐버려 T1/T3/L4에서 오히려 성능 하락.

3 결과

4단계 그래프 비교 (전체 정확도)

그래프Objects전체L1L2L3L4
Raw76964.1%54.1%61.5%79.0%50.0%
Norm1 (regex)53567.9%62.4%62.0%80.2%75.0%
Norm2 (+VLM dedup)30065.9%57.5%61.5%80.2%66.7%
Baseline (20 frames)70.0%67.4%65.5%78.4%66.7%

정규화 효과 (Raw → Norm1)

카테고리RawNorm1Δ
L4 (장기기억)50.0%75.0%+25.0%p
EM5 (과정)66.2%80.5%+14.3%p
T3 (인과)69.0%79.3%+10.3%p
EM3 (시간기억)57.5%63.2%+5.7%p

Graph가 Baseline을 이기는 영역 (Norm1 기준)

L3 (Cross-event): 80.2% vs 78.4% — 그래프의 구조적 이점이 드러나는 유일한 수준
L4 (Long-term): 75.0% vs 66.7% — 장기 기억에서 확실한 우위. 그래프가 설계 목적에 부합

Overlap 분석 (Raw 기준)

상태수량의미
둘 다 맞음286쉬운 질문 (공통 강점)
Graph만 맞음73그래프의 고유 가치 영역
Baseline만 맞음106그래프가 놓친 영역
둘 다 틀림95공통 한계

4 Takeaway

핵심 인사이트

Regex 정규화 (Norm1)가 sweet spot. 기계적이라 보수적이기 때문 — 명백한 동일성만 합쳐서 정보 손실 없이 중복 제거. VLM dedup (Norm2)는 공격적 매칭으로 정보 손실을 유발했음. 교훈: 이후 dedup은 "merge 해도 구분력 손실 없는 경우만" 보수적으로.

그래프의 진짜 가치: Long-range Reasoning

L4 (장기기억)에서 Norm1 기준 75% vs Baseline 66.7%. Raw에서 이미 L3(79% vs 78.4%)가 유일한 우세 영역이었고, 정규화로 이 이점이 더 선명해짐. 그래프는 구조화된 맥락 압축으로 장거리 집계에 강함. 단순 프레임 관찰로는 27.5분 전체 이벤트를 집계하는 질문에 취약.

EM3 (시간 기억)이 예상과 달리 무승부: 1분 구간에선 Graph 100% vs Baseline 33%였는데, 27.5분에선 63.2% vs 57.5%로 좁혀짐. 이유: 20프레임이 27.5분에 분산되면서 VLM도 대략적 시간 추정 가능해짐.

5 Next Steps

즉시 개선

Multi-object query: participant(zucchini) 대신 participant([zucchini, diced_zucchini, zucchini_slices]) 자동 확장. Query fallback 강화 (결과가 적으면 broader query로 자동 확장).

Describe-Once Baseline 추가

Frame 20장이 아닌 VLM description을 통째로 context로 쓰는 공정한 비교 baseline 필요. 그래프가 같은 정보 소스에서 출발했을 때 부가가치를 만드는지 직접 측정.

구조 개선

Graph builder의 incremental entity tracking (프레임 간 이전 object 목록 전달). Action-chain tracking for movable objects (celery: sink → cutting board → pan → fridge).