AI 분석
2026-09-18 기준 · 담당 정상호. 설계 의도는 시스템 설계 3·4절에 있다. 이 장은 무엇을 만들었고, 무엇에 막혔고, 어떻게 풀었나를 다룬다.
1) 맡은 것 한눈에
영상 한 편을 받아 자세를 재고, 항목별로 채점하고, 왜 그 등급인지 문장으로 설명하는 구간을 맡았다. 영상을 받아 두는 것과 결과를 담는 것은 백엔드(정어진), 보여 주는 것은 화면(백성검) 쪽이다.
2) 설계의 중심 — 측정과 판단을 가른다
언어 모델은 수치를 만들지 않고 등급도 정하지 않는다. 재는 것과 등급을 매기는 것은 전부 결정론적 코드가 하고, 모델은 이미 정해진 등급에 대해 자세를 서술하는 문장만 쓴다.
처음에는 모델에게 등급까지 맡겼다. 그런데 기준선이 140도인 항목에서 141.7도를 아래 등급으로 판정했다 — 그것도 매번 같은 방식으로 틀렸다. 사람이라면 헷갈릴 수 없는 자리이고, 여기서 한 번 밀리면 총점과 호칭이 통째로 달라진다. 그래서 판정을 코드로 옮겼고, 그 경로는 다시 열지 않기로 했다.
| 하는 일 | 누가 |
|---|---|
| 관절 좌표 추출 · 지표 계산 | 결정론적 코드 |
| 항목별 등급 판정 · 합산 · 호칭 | 결정론적 코드 |
| 왜 그런지 설명하는 문장 | 언어 모델 |
같은 이유로 등급 낱말은 문장에 넣지 않는다. 「잘함」·「아쉬움」 같은 표기는 코드가 붙이고, 모델이 쓴 문장에는 자세만 담는다. 문장에서 등급을 되짚어 읽으려는 시도는 하지 않는다 — 문자열로 칭찬과 지적을 가르려다 검사 쪽이 먼저 틀렸다.
3) 8GB에서 돌린다는 제약
개발 GPU가 8GB(실사용 약 7.4GB)라, 설계 판단 몇 개가 여기서 나왔다.
- 자세 추출 모델과 판정 모델을 동시에 올리지 않는다. 추출이 끝나면 해제하고 메모리를 비운 뒤 판정으로 넘어간다
- 판정 모델을 양자화하지 않는다. 4bit가 늘 이득일 것 같지만 실측은 반대였다 — 적재 44.2초·초당 11.5토큰으로, bf16의 7.5초·24.4토큰보다 느렸다. 작은 모델에서는 되돌리는 비용이 아끼는 메모리보다 크다
- 영상을 보는 모델은 쓰지 않는다. 판정은 수치만으로 한다. 그래서 무엇을 재는지가 곧 무엇을 볼 수 있는지가 된다
4) 막힌 것과 푼 것
같은 영상이 촬영 설정에 따라 다른 점수를 받았다
초당 15장으로 줄여 보던 것을 30장으로 올렸다. 임팩트처럼 짧은 순간의 각속도 피크가 프레임 사이로 빠져, 같은 동작이 촬영 프레임레이트에 따라 다른 값으로 읽혔기 때문이다. 🔴 이 변경은 「정확해졌다」가 아니라 「동작점을 옮겼다」이다 — 정답이 없는 영역이라 무엇이 더 맞는지는 아직 말할 수 없고, 적어도 입력 설정에 덜 흔들리는 자리로 옮긴 것이다.
화면 속 사람이 여럿일 때 엉뚱한 사람을 쟀다
처음에는 가장 큰 사람 박스를 대상으로 삼았다. 관중이나 심판이 더 크게 잡히는 구도가 실제로 있었고, 실클립에서 타자를 따라가던 추적이 심판으로 갈아타 190프레임(63%)을 다른 사람으로 분석한 일이 있었다.
그래서 사용자가 대상을 지정할 수 있게 하고, 지정이 없을 때만 자동 규칙을 쓴다. 추적은 아직 완전하지 않다 — 대신 지정한 사람을 끝까지 따라간 것으로 보이는지, 도중에 바뀐 의심이 있는지를 결과에 함께 싣는다. 고치지 못한 것을 숨기지 않는 것과, 안 한 일을 했다고 말하지 않는 것은 다른 문제이고, 뒤쪽은 지금 고칠 수 있었다.
촬영 방향이 점수에 섞여 들어간다
상체 기울기·골반 회전처럼 카메라 축에 의존하는 지표는 선수의 자세뿐 아니라 어느 쪽에서 찍었는지를 함께 잰다. 축구 18편으로 확인해 보니 항목 등급은 18편 전부, 최종 등급은 8편이 촬영 방향에 따라 흔들렸다.
고치는 길은 둘 다 막혀 있었다 — 임계값을 옮기려면 지도자 검수가 필요한데 섭외가 안 됐고, 다른 각도의 표본은 아직 0편이다. 그래서 고쳤다고 하지 않고 드러내기로 했다: 그런 항목에는 「촬영 방향에 따라 달라질 수 있음」이 결과에 함께 나간다. 🔴 결함이 없어진 것이 아니라 아직 고치지 않은 것이고, 그렇게 적어 두는 편이 조용히 틀린 값을 내는 것보다 낫다고 판단했다.
같은 코드가 같은 결과를 안 냈다
과거에 낸 기준선이 현재 코드로 재현되지 않았다. 커밋을 되돌려 봐도 전부 어긋나서 코드 문제가 아니었고, 원인은 의존성 하나가 빠지면서 전처리기가 조용히 다른 것으로 골라진 것이었다. 이미지 크기 조정이 미세하게 달라지면 검출 상자는 멀쩡한데 그 뒤가 흔들린다.
여기서 배운 것을 규칙으로 남겼다 — 모델 가중치는 이름이 아니라 판(버전)으로 고정하고, 평가에 쓰는 자산은 한 벌만 두지 않는다. 테스트가 이 둘을 지킨다.
설명 문장이 자기 등급과 반대로 말한다
감점을 받은 항목인데 칭찬처럼 서술하는 문장이 남아 있다. 프롬프트 쪽에서 아홉 번을 손봤고, 그중 넷은 재 보고 되돌렸다 — 한쪽 오독을 줄이면 다른 쪽이 늘어나는 맞바꿈이 반복됐기 때문이다. 지금은 방향 오독이 감점 30자리 중 4건, 칭찬 22자리 중 1건이다.
되돌린 길은 왜 닫혔는지를 숫자와 함께 코드 주석과 회차 기록에 남겼다. 같은 벽에 다시 부딪히지 않기 위해서다. 남은 선택지는 문장을 코드가 조립하는 방식과 더 큰 모델, 그리고 미세조정이고 아직 정하지 않았다.
5) 일하는 방식 — 정답이 거의 없는 영역이라서
이 영역에는 「맞는 답」이 대개 없다. 그래서 스스로를 속이지 않기 위한 규칙을 몇 개 두고 지킨다.
- 고치기 전에 합격·불합격을 수치로 먼저 적는다. 결과를 보고 기준을 고치지 않는다 — 이 규칙 때문에 「좋아 보이는」 변경 넷을 되돌렸다
- 조사와 구현을 섞지 않는다. 재는 회차에는 제품 코드를 건드리지 않는다
- AI 단독 판독을 정답으로 승격하지 않는다. 「갈리지 않는다」 같은 부정적 결론의 근거로는 쓰되, 그것으로 학습 목표를 만들지 않는다
- 「정확해졌다」고 쓰지 않는다. 정답이 없으면 달라진 것이지 나아진 것이 아니다
6) 지금 상태와 남은 것
| 도는 것 | 영상 한 편 → 항목별 등급·총점·호칭·근거 문장·선수용 카드 문구, 그리고 대상 선수 추적 상태 |
| 시간 | 분석 한 편 72~125초(개발 환경). 판정을 한꺼번에 던지도록 바꿔 그 구간이 12.6 → 4.0초, 미리보기 인코딩이 28.1 → 3.5초로 줄었다 |
| 재현성 | 같은 측정값으로 세 번 판정해 총점 동일(표준편차 0.00) |
| 🔴 남은 것 | 설명 문장의 방향 오독 · 촬영 방향 의존 · 지도자 검수 없이 확정한 임계값 · 미세조정은 아직 판정 전 |
루브릭 자체가 아직 검수를 받지 않았다. 그래서 점수는 잠정이고, 화면에는 총점보다 호칭과 장단점을 앞세운다 — 있는 근거보다 더 많이 말하지 않기 위해서다.