G1 보행 정책을 어떻게 학습하고 있는가 — PPO 루프와 지금 학습을 멈춘 이유

G1이 넘어지지 않고 앞으로 걸었습니다. 처음에는 이것만으로 학습이 성공했다고 생각하기 쉽습니다. 하지만 최근 실험에서 가장 중요한 판단은 새 체크포인트를 채택한 일이 아니라, 겉으로는 걷는 두 체크포인트를 연달아 탈락시킨 일이었습니다. v590은 느린 보행 평가에서 기존 기준보다 0.7199 m 덜 갔고, v600은 0.2479 m 덜 갔습니다. 둘 다 낙상과 발 교차는 없었지만 새 기준 모델이 되지 못했습니다.

이 결과를 겪고 나서 저는 G1 학습 방법을 다시 정의했습니다. 지금의 방법은 “PPO를 오래 돌려 보행을 만든다”가 아닙니다. 정책을 바꾸는 학습 루프와, 그 정책을 다음 학습의 출발점으로 인정할지 결정하는 증거 루프를 분리합니다. 보상 합계가 올라가거나 시뮬레이터 화면이 그럴듯하다는 이유만으로 체크포인트를 승격하지 않습니다.

G1 보행 정책의 PPO 학습 루프와 고정 조건 평가·하드 게이트·체크포인트 승인으로 구성된 별도 증거 루프
PPO는 후보 정책을 만들 뿐입니다. 고정 조건과 하드 게이트를 통과한 결과만 다음 학습의 기준으로 돌아갑니다. 현재는 M160a 비학습 실험까지만 열려 있습니다.

G1이 한 번의 정책 추론에서 보는 것

현재 환경은 Unitree G1의 29개 관절을 제어합니다. 물리 시뮬레이션은 200 Hz로 진행하고, 네 번의 물리 스텝마다 정책을 한 번 호출하므로 정책 주파수는 50 Hz입니다. 정책 입장에서는 20 ms마다 현재 상태를 보고 다음 관절 목표를 내는 셈입니다. 학습할 때는 같은 환경을 4,096개 병렬로 실행합니다.

정책에 들어가는 관측은 73차원입니다. 몸통의 선속도와 각속도, 몸통 좌표계에서 본 중력 방향, 목표 속도, 보행 위상의 사인·코사인, 다음에 들어야 할 발, 29개 관절의 기준 자세 대비 위치, 29개 관절 속도로 구성됩니다. 카메라 영상을 직접 넣는 VLA 학습이 아니라, 로봇의 상태 벡터를 입력으로 받는 저수준 보행 정책입니다. 자연어 명령이나 시각 인식은 나중에 이 정책 위에서 목표 속도나 태스크를 정하는 상위 계층의 역할입니다.

출력은 29차원의 raw action입니다. 이 값을 관절 각도로 바로 쓰지 않고, 기본 자세에 스케일을 적용해 더합니다.

q_target = q_nominal + 0.25 × action

여기서 q_nominal은 G1의 기본 관절 자세입니다. action은 기본적으로 ±4 범위에서 잘리고, 실험에 따라 허리·고관절·팔처럼 관절 그룹별로 더 좁은 경계를 적용합니다. 이 중간 계층이 중요한 이유는 actor가 같은 숫자를 내더라도 실제 로봇 자세에 미치는 영향이 관절마다 다르기 때문입니다. 팔의 과도한 흔들림을 줄이려면 보상만 바꾸는 방법과 action interface에서 허용 범위를 바꾸는 방법을 구분해야 합니다.

PPO는 98,304개의 전이를 모아 한 번 갱신합니다

학습 알고리즘은 RSL-RL의 PPO입니다. 하나의 환경에서 24스텝을 모으고 4,096개 환경을 병렬로 사용하므로, 한 번의 갱신에 98,304개의 상태 전이가 들어갑니다. actor와 critic은 각각 512-256-128 크기의 MLP이고 활성화 함수는 ELU입니다. PPO clip은 0.2, discount factor는 0.99, GAE의 lambda는 0.95입니다. 모은 데이터는 4개 미니배치로 나누어 5 epoch 동안 학습합니다.

설정 파일에는 최대 3,000 iteration을 실행할 수 있게 되어 있지만, 이것이 현재 실험을 무조건 3,000번씩 돌린다는 뜻은 아닙니다. 최근 보상과 형태 개선 실험은 승인된 기준 체크포인트에서 단 한 번의 PPO iteration만 허용한 smoke test로 시작했습니다. 한 번의 갱신만으로도 보행 경로가 훼손된다면 더 오래 돌리는 것은 개선이 아니라 실패를 증폭할 가능성이 높기 때문입니다.

학습 스크립트는 실행할 때 환경·보상·action profile을 검증하고, 실험마다 별도 디렉터리와 run manifest를 만듭니다. 기존 체크포인트에서 시작할 때도 resume 대상을 명시합니다. 어떤 부모 체크포인트와 설정으로 결과가 생겼는지를 남겨야, 화면상 움직임이 달라졌을 때 원인을 보상·관측·action interface·학습 자체로 나누어 추적할 수 있습니다.

보상 함수보다 먼저 확인한 세 가지 실패

G1의 reward는 단순히 “앞으로 가면 +1″로 만들지 않았습니다. 몸통 좌표계에서 명령 속도를 따라가는 항목과 월드 좌표계에서 실제로 전진하는 항목을 함께 둡니다. 몸이 180도 돌아간 채 자신의 앞쪽으로 움직이면 body-frame 속도 오차만으로는 좋은 점수를 받을 수 있기 때문입니다. 여기에 속도 미달·후진·과속·상체 기울기·높이·발 접촉과 미끄러짐·action 변화량·관절 형태 항목을 reward profile별로 조합합니다.

하지만 보상 계수를 만지기 전에 환경과 신호가 의도대로 작동하는지부터 확인해야 했습니다. 초기에 발 공중 시간 보상식은 목표 시간보다 짧게 발을 들면 음의 값을 주었습니다. 발을 조금이라도 들기 시작한 정책이 오히려 벌점을 받으니 로봇은 발을 들지 않는 쪽으로 수렴했습니다. 수식을 고친 뒤에야 air-time 보상이 의도한 방향으로 작동했습니다.

두 번째 문제는 alive reward였습니다. 살아 있기만 해도 받는 보상이 전진 보상보다 강하면, 정책은 걷는 대신 넘어지지 않는 자세를 찾습니다. 그래서 alive 항목의 비중을 낮추고 월드 좌표계 전진량을 직접 보상에 넣었습니다. 세 번째 문제는 커스텀 USD와 actuator gain이었습니다. zero policy에서도 발목 토크가 포화되고 2.6~2.7초 부근에서 반복적으로 무너지는 현상이 reward 조정으로 해결되지 않았습니다. 결국 공식 Unitree 에셋과 actuator 설정으로 전환했습니다. 이 세 사례는 학습 실패처럼 보이는 현상이 실제로는 보상식의 부호, 보상 간 우선순위, 또는 로봇 모델 설정의 문제일 수 있음을 보여줍니다.

느린 보행과 정상 보행을 따로 가르치고 따로 평가합니다

현재 속도 curriculum은 대부분의 샘플을 0.45~0.55 m/s의 느린 보행에 배정하고, 일부를 0.90~1.00 m/s의 정상 보행에 둡니다. 정지 명령도 소량 포함합니다. 느린 속도를 많이 보여 주는 이유는 단순합니다. 속도가 낮아지면 한 발 지지 구간과 관절 형태의 작은 문제가 더 오래 드러나고, 정상 속도에서 관성으로 가려지던 발 끌림이나 팔의 간섭을 관찰하기 쉬워집니다.

학습 분포와 평가는 분리합니다. 평가에서는 느린 조건과 정상 조건을 고정하고, 같은 seed와 같은 시간 구간으로 후보와 기준 체크포인트를 비교합니다. 낙상 여부 외에도 발 교차율, 좌우 발의 최소 간격, 허리와 고관절의 편차, 팔 위치·속도, commanded action과 raw action을 함께 봅니다. 화면에서 보기에 자연스럽다는 판단을 수치로 대체하려는 것이 아니라, 자연스러워 보이는 움직임 뒤에 숨은 위험을 놓치지 않기 위한 장치입니다.

승격 gate의 핵심은 비퇴행입니다. 최근 실험에서는 느린 평가의 이동거리 감소를 -0.05 m 이내, 정상 평가를 -0.10 m 이내로 제한했습니다. 낙상과 발 교차는 0이어야 하고, 짧은 평가만 우연히 통과하는 것을 막기 위해 5초 및 15초 trace의 최종 이동거리와 형태 지표도 다시 확인했습니다. 한 항목이 좋아져도 기존 보행 경로를 잃으면 새 기준으로 채택하지 않습니다.

v590과 v600은 왜 걸었는데도 탈락했을까요

v590은 기존 v585 기준에서 새 reward profile을 적용해 한 번의 PPO 갱신을 수행한 결과입니다. 느린 조건 이동거리는 2.8568 m에서 2.1369 m로 0.7199 m 줄었습니다. 팔 raw action도 미세하게 나빠졌습니다. 정상 속도와 낙상·교차 지표는 보존됐지만 느린 보행 경로 gate를 크게 벗어났기 때문에 model6507을 새 기준으로 올리지 않았습니다.

v600에서는 reward 압력을 다시 조정했습니다. 정상 속도는 8.1769 m에서 8.1776 m로 사실상 유지됐고 낙상과 교차도 없었습니다. 그러나 느린 속도는 2.6089 m로 기준보다 0.2479 m 부족했고, 전체 morphology/raw-action gate도 통과하지 못했습니다. 이어서 수행한 15초 trace에서는 느린 보행 최종 이동거리 차이가 -0.5444 m까지 벌어졌습니다.

reward 항목이 아예 작동하지 않은 것은 아니었습니다. 학습 중 해당 항목의 압력이 실제로 관측됐습니다. 현재 기록에서 가장 설득력 있는 해석은 정책이 나쁜 팔 형태를 고치는 대신, 느린 보행 경로의 품질을 낮춰 형태 벌점이 발생하는 상태 자체를 회피했다는 것입니다. 다만 이것은 trace가 지지하는 작업 가설이지 확정된 일반 법칙은 아닙니다. 그렇기 때문에 같은 종류의 scalar reward를 조금씩 바꿔 PPO를 반복하는 방법은 중단했습니다.

지금은 학습 대신 오른팔의 인과관계를 측정하고 있습니다

PPO를 멈춘 뒤에는 오른팔 움직임이 발 clearance와 접촉에 실제로 영향을 주는지 분리해 확인했습니다. M158d의 동일 seed 재생에서는 접촉 횟수가 87회에서 71회로, 충격량이 9.8347 N·s에서 7.6006 N·s로 줄었습니다. 오른팔 자극이 동역학에 영향을 준다는 신호입니다. 그러나 요구한 25% 접촉 감소에는 못 미쳤고, 최소 clearance는 -0.151 mm에서 -0.826 mm로 오히려 악화됐습니다. washout gate도 실패했습니다. “팔이 영향을 준다”와 “팔을 이렇게 제어하면 보행이 좋아진다”는 서로 다른 주장이라는 뜻입니다.

후속 M159에서는 독립적인 첫 반응이 17개뿐이었고, 44열 lag 설계의 rank가 27에 그쳤습니다. 고정 lag 5에서는 17개 primary 환경 모두 clearance가 좋아졌지만, 표본 수·설계 rank·예측 안정성 조건을 충족하지 못했습니다. 좋아 보이는 국소 효과를 근거로 PPO를 재개하지 않고 teacher-overlay 계열을 세 번의 사이클에서 종료했습니다.

현재 승인된 M160a의 범위는 더 좁습니다. 오른팔만 자극하는 비학습 CPU 실험 설계이며, 128개의 reset pair와 44열 full-rank 설계를 사용합니다. CPU 계약 테스트는 7/7을 통과했고 정규화 조건수는 17.457, leave-one-pair-out 최대 조건수는 17.758입니다. 이것은 실험 설계가 계산상 성립한다는 확인일 뿐, Isaac Sim 실행이나 PPO 재개를 승인한 결과는 아닙니다.

다음 단계는 기존 산출물을 덮어쓰지 않는 별도 경로에서 post-policy/pre-physics 지점의 값을 기록하는 runtime-capture 제안입니다. 구현과 실행 후 검토를 다시 통과해야 M160b의 actor 또는 constrained algorithm을 논의할 수 있습니다. M148 model1850은 비교 기준일 뿐 학습 부모로 승인되지 않았고, 체크포인트 승격도 닫혀 있습니다.

현재 G1 학습 방법을 한 문장으로 정리하면

현재의 G1 학습 방법은 대규모 병렬 PPO로 후보를 만들고, 학습과 분리된 고정 조건 평가에서 보행 경로와 관절 형태를 동시에 보존한 후보만 다음 기준으로 승격하는 방식입니다. 그리고 같은 실패가 반복되면 reward를 더 조정하기 전에 학습을 멈추고, 원인을 분리하는 비학습 실험으로 돌아갑니다.

이 방식은 빠르게 좋아 보이는 영상을 만드는 데는 불리할 수 있습니다. 대신 어떤 변경이 실제로 보행을 개선했는지, 무엇은 아직 가설인지, 다음 PPO를 시작할 근거가 있는지를 구분할 수 있습니다. 지금 G1에서 가장 중요한 성과는 새 모델 번호가 아니라, 학습을 계속하지 않아야 할 이유를 수치로 설명할 수 있게 된 것입니다.

관련 글: 로봇에게 자연어 명령을 내리기까지: 제가 구축 중인 Physical AI 파이프라인 · 휴머노이드 보행은 무엇으로 평가해야 하는가 · 학습과 실험을 멈추는 기준 · Learning to Walk in Minutes

참고 자료: Learning to Walk in Minutes Using Massively Parallel Deep Reinforcement Learning · RSL-RL 공식 저장소

기술 기준 시점: 2026-07-21. 환경·평가 수치와 현재 승인 경계는 origin/main@ee4d96e의 G1 설정, 평가 코드, NEXT_RUN_NOTES를 기준으로 작성했습니다.

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

위로 스크롤