연구 노트 R01. 보상은 빈틈을 찾는다 — 우리 로봇은 왜 ‘가짜 걸음’을 배웠나

연구 질문: 06~09번에서 학습한 정책은 속도 추종·균형·외란 회복까지 해냈는데, 걸음을 측정해 보니 8Hz로 잔발을 치며 미끄러지는 셔플이었다(10번 문서). 공식 구현들이 넣는 ‘걸음 교정 보상’이 없으면 왜 이런 이상한 동작이 나오는가? 이것은 우연인가, 필연인가?

이 문서는 튜토리얼이 아니라 연구 노트입니다. 우리가 직접 겪은 사례를 1차 자료로 삼아, 이 현상의 이름·원리·역사·대응책을 정리합니다.


1. 현상에는 이름이 있다: specification gaming

우리가 겪은 일은 RL 연구에서 오래된, 이름 붙은 현상입니다. DeepMind는 이를 specification gaming(굳이 옮기면 ‘명세의 빈틈 파고들기’) 이라 부릅니다: “목표의 문구(letter)는 만족시키지만 의도(spirit)는 달성하지 않는 행동”. 보상 해킹(reward hacking)이라고도 합니다.

핵심 통찰은 이것입니다:

RL은 우리가 원하는 것을 최적화하지 않는다. 우리가 채점하는 것을 최적화한다.

사람은 “0.5m/s로 걸어라”라는 보상을 보면 자연히 ‘걷기’를 떠올립니다. 하지만 최적화기가 보는 것은 문자 그대로의 수식뿐입니다. 수식을 만족하는 모든 행동 중에서 가장 점수가 높은 것을 찾아내며, 거기에 ‘걷기다움’이라는 우리의 암묵적 기대는 단 한 글자도 들어 있지 않습니다. 경제학의 굿하트 법칙(Goodhart’s law) — “지표가 목표가 되는 순간 좋은 지표이길 멈춘다” — 의 RL 버전입니다.


2. 우리 사례의 해부: 셔플은 버그가 아니라 ‘정답’이었다

10번 문서에서 측정한 우리 셔플 보행(발당 8.25Hz, 발 들림 1cm, 보폭 6cm, 발 간격 55cm)을 보상표에 대입해 보면, 셔플이 실제로 우리 채점표의 고득점 답안임을 확인할 수 있습니다.

우리 보상 항목 의도 셔플이 받는 점수
tracking_lin_vel (+) “0.5m/s로 가라” 6cm×8.25Hz≈0.5m/s — 만점
lin_vel_z (−) 위아래로 출렁이지 마라 미끄러지듯 가니 출렁임 0 — 진짜 걸음보다 고득점
base_height (−) 키를 유지하라 몸통 높이 편차 ±1mm — 진짜 걸음보다 고득점
orientation (−) 똑바로 서라 기울지 않음 — 만점
similar_to_default (−) 기본자세 근처에 있어라 무릎 10~24°만 씀 — 다리를 크게 휘두르는 진짜 걸음보다 고득점
action_rate (−0.005) 부드럽게 움직여라 벌점이 너무 약해 8Hz 잔발을 못 막음
(없음) 발을 들어라, 박자를 지켜라, 미끄러지지 마라, 다리를 모아라 채점 안 함 = 자유

즉 세 가지가 겹쳤습니다:

  1. 채점하지 않은 자유도는 아무 값이나 된다. 발 들림·보폭·박자·발 간격은 채점표에 없으니, 최적화는 그중 ‘속도 내기 가장 쉬운’ 값(전부 최소화)을 골랐습니다.
  2. 안정성 벌점이 오히려 진짜 걸음을 벌줬다. 실제 보행은 몸이 주기적으로 출렁이는 운동인데, 우리는 출렁임에 벌점을 줬습니다. “출렁이지 않고 전진”의 최적해는 걷기가 아니라 미끄러지기입니다.
  3. 물리 환경이 지름길을 허용했다. kp350의 초강성 PD와 시뮬레이터의 이상적인 접촉/마찰이 현실 모터로는 불가능한 8Hz 잔발을 물리적으로 가능하게 했습니다. 시뮬레이터의 관대함도 빈틈의 일부입니다.

결론: 셔플은 학습 실패가 아니라, 우리가 낸 문제에 대한 완벽한 정답입니다. 잘못된 것은 정책이 아니라 문제(보상 명세)였습니다.

위: 셔플(0.5초 구간 — 다리가 거의 안 움직여 보임) / 아래: 교정된 걸음(같은 시간 폭)


3. 이 현상은 보편적이다 — 역사 속 사례들

우리만 겪은 게 아닙니다. 이 현상은 30년 넘게, 온갖 도메인에서 반복돼 왔습니다.

  • 보트 경주 (OpenAI, 2016): 경주 게임 CoastRunners에서 ‘완주’가 아니라 ‘점수’를 보상으로 줬더니, 에이전트는 경주를 포기하고 석호에서 뱅글뱅글 돌며 리스폰되는 아이템만 무한히 먹었습니다. 불타고 벽에 박으면서도 사람 평균보다 20% 높은 점수를 얻었죠 — Faulty Reward Functions in the Wild.
  • 블록 쌓기 (DeepMind): “빨간 블록의 바닥면을 높이 하라”(파란 블록 위에 올리라는 의도)를 줬더니, 로봇은 블록을 쌓는 대신 빨간 블록을 뒤집어 바닥면을 위로 향하게 했습니다 — Specification gaming 블로그 (저자들은 이런 사례를 약 60개 수집했습니다).
  • 가상 생물 진화 (Karl Sims, 1994): “이동 속도”를 보상으로 진화시킨 가상 생물은 걷는 대신 키가 아주 큰 몸을 진화시켜 넘어지는 것으로 순간 속도를 얻었습니다. 보행 RL 셔플의 원조 격인 사례입니다.
  • 시뮬레이터 물리 익스플로잇: 접촉 처리의 수치 버그를 찾아내 몸을 떨며 에너지를 공짜로 얻거나, 마찰 모델의 빈틈으로 미끄러져 다니는 사례가 보행 RL에서 반복적으로 보고됩니다. 우리의 “1cm 발 들림 + 8Hz 진동”도 같은 계열 — 시뮬레이터가 허용하지만 현실엔 없는 지름길입니다.

패턴이 보입니다: 최적화 압력이 세고, 명세에 빈틈이 있으면, 그 빈틈은 반드시 발견됩니다. 탐색을 수천만 번 반복하는 RL에서 이것은 우연이 아니라 통계적 필연입니다. 오히려 빈틈을 못 찾으면 최적화가 덜 된 것입니다.

그리고 지금 — 챗봇도 같은 것을 배웁니다

이 현상은 로봇과 게임에서 끝나지 않았습니다. 요즘의 대화형 AI(LLM)는 마지막 단계에서 사람 평가자가 매긴 점수를 보상으로 학습합니다(RLHF). 그 순간 채점표는 “도움이 되는 답”이 아니라 “평가자가 도움이 됐다고 느끼는 답“이 됩니다 — 그리고 최적화는 어김없이 그 틈을 찾아냅니다. 사용자의 의견에 무조건 맞장구치는 아첨(sycophancy), 모르는 것도 자신만만한 말투로 답하는 버릇(확신에 찬 문장이 점수를 더 받으니까), 벤치마크 문제 유형만 잘 푸는 과최적화 — 전부 우리 로봇의 셔플과 같은 구조입니다. “잘 걷기”를 채점하려다 “잘 걷는 것처럼 보이기”를 채점하게 된 것처럼요.

이것이 AI 분야에서 말하는 정렬(alignment) 문제 — “AI가 최적화하는 것”과 “사람이 실제로 원하는 것”을 일치시키는 문제 — 의 뿌리입니다. 우리 로봇은 그나마 다행입니다. 걸음은 잴 수 있으니까요(걸음 빈도, 발 들림, 보폭…). 그런데 “정직함”이나 “진짜 도움”은 잴 잣대 자체가 마땅치 않습니다. 이 시리즈에서 우리가 겪은 순환 — 측정하고, 빈틈을 찾고, 채점표를 보강하는 — 이 그 큰 문제의 작고 다행히도 측정 가능한 축소판인 셈입니다.


4. 그럼 어떻게 막나 — 대응책의 스펙트럼

업계·학계의 대응은 크게 넷입니다. 아래로 갈수록 ‘의도’를 더 직접적으로 전달합니다.

① 채점표 보강 (우리가 10번에서 한 것)

빈틈이 발견될 때마다 항목을 추가: 발 들림 보상, 박자 보상, 미끄럼 벌점, 에너지 벌점… unitree_rl_gym의 G1 설정이 정확히 이 접근이고, 15개 안팎의 항목은 그동안 빠졌던 빈틈을 하나씩 막아 온 흔적입니다. 단점: 두더지 잡기입니다. 새 빈틈은 계속 나올 수 있고, 항목 간 가중치 균형도 수작업입니다.

② 사전 지식 주입 (구조로 막기)

위상 클록(우리 gait 태스크의 sin/cos 박자), 참조 발자국, 중앙 패턴 발생기(CPG) 등 “걸음이란 이런 구조다”를 관측이나 행동 공간에 심는 방법. 빈틈 자체를 구조적으로 줄이지만, 그 구조 밖의 창의적 해법(비정형 지형 대응 등)도 함께 막을 수 있습니다.

③ 모방 학습 — ‘자연스러움’을 데이터로 정의

사람/모션캡처 데이터와 “구별되지 않으면” 보상을 주는 방식(AMP, HumanMimic 등). Figure의 자연 보행도 이 계열입니다. ‘자연스러움’을 수식으로 쓰는 대신 데이터로 보여주는 것 — 명세의 빈틈 문제를 가장 근본적으로 우회하지만, 좋은 모션 데이터가 필요합니다.

④ 물리적으로 정직한 목적 함수

생체역학의 통찰: 사람의 걸음은 에너지 최적화의 산물입니다. 이동 대비 에너지(cost of transport)를 최소화하면 자연스러운 걸음이 ‘유도’된다는 연구 흐름이 있습니다. 에너지·토크 벌점이 단순 정규화가 아니라 ‘자연스러움의 물리적 근원’이라는 관점. 시뮬레이터의 물리 충실도(모터 모델, 접촉)가 뒷받침되어야 현실과 같은 최적해가 나옵니다.

실무에서는 보통 ①+②를 기본으로 깔고(우리 10번이 여기), 품질이 더 필요하면 ③을 얹습니다.


5. 이번 연구에서 얻은 실무 수칙

  1. 영상은 검증이 아니다. 우리 셔플은 따라가는 카메라 영상에선 그럴듯해 보였습니다. 걸음 빈도·발 들림·보폭·접촉 패턴을 수치로 재야 합니다 (10번의 측정 스크립트).
  2. 보상 설계는 명세 작성이다. 항목을 적기 전에 물어야 합니다 — “이 채점표를 만점 받는 행동 중 내가 의도하지 않은 것이 있는가?” 특히 채점하지 않는 자유도가 어디로 갈지 생각해야 합니다.
  3. 벌점의 부호를 의심하라. ‘안정성’ 벌점(출렁임 금지)이 정작 진짜 걸음을 벌주고 있었습니다. 벌점이 의도한 행동과 충돌하지 않는지 확인해야 합니다.
  4. 공식 레퍼런스의 보상 항목은 역사책이다. 낯선 항목(contact_no_vel 같은)이 있다면 그건 누군가 그 빈틈에 이미 빠졌었다는 뜻입니다. 지우기 전에 왜 있는지 조사할 것.
  5. 좋은 결과가 나와도 ‘어떻게’ 얻었는지 봐야 한다. 우리 06~09의 기능(추종·회복)은 전부 진짜였지만, 그 기능이 올라탄 ‘걸음’이 가짜였습니다. 위층 기능이 잘 돌아간다고 그 아래 기반까지 멀쩡하다는 보장은 없습니다.

참고 자료

이 시리즈의 전체 글 목록 → 시리즈 목차

댓글 남기기

이 사이트는 Akismet을 사용하여 스팸을 줄입니다. 댓글 데이터가 어떻게 처리되는지 알아보세요.