《GPU Mode》
L054
2024
High priority
transcript · failed
Small RL Models at the Speed of Light — LeanRL
작은 정책 모델 (수백 KB ~ 수십 MB) 의 RL 학습이 GPU 의 어디서 발목 잡히는가 — 그리고 LeanRL 이라는 PyTorch 기반 프레임워크가 그 발목을 어떻게 풀어내는지의 학습 노트. 강의 transcript 가 실패해 본 페이지는 LeanRL 의 공개 repo 와 일반적 RL 인프라 지식으로 재구성됐다 — speaker 정보가 없어 해당 항목은 비워둠.
LeanRL
small RL models
vectorized envs
actor-learner
PyTorch
cudagraph
torch.compile
PPO / SAC
§ 01강의가 풀려는 문제· why this lecture exists
“수백 KB 짜리 정책 모델인데 왜 GPU 의 1% 도 못 쓰나” 의 답
RL 학습 — 특히 PPO / SAC 같은 on-policy 또는 off-policy 학습 — 의 한 step 안에서 모델 forward 가 1ms 이하로 끝난다. 그 짧은 시간에 GPU launch overhead, environment step, replay sampling, gradient update 가 모두 끼어든다. 결과 — GPU 사용률이 5%~30% 사이.
강의가 던지는 두 질문.
- RL 학습의 병목이 정확히 어디인가 — 작은 모델이라 compute 가 아니다. 그러면 launch overhead, host-device 전송, environment step 중 어디?
- 그 병목을 어떻게 풀 수 있나 — vectorized env, cudagraph, torch.compile 의 조합으로.
본 노트는 transcript 실패로 — LeanRL repo (github.com/pytorch-labs/LeanRL) 의 README, 일반적 RL 인프라 지식 (CleanRL, Stable Baselines, IsaacGym 등), 그리고 PyTorch torch.compile / cudagraph 의 동작 원리로 재구성. speaker 정보가 누락되어 본문에 “speaker 의 인용” 형식 안 씀.
강의의 frame
RL 의 GPU 활용은 “모델이 작아서 어쩔 수 없다” 가 통념. LeanRL 의 입장은 — 그 통념이 틀렸다는 것. 작은 모델도 (1) env 를 GPU 로 옮기고, (2) launch overhead 를 cudagraph 로 죽이고, (3) compile 로 fusion 하면 — GPU 의 60~80% 까지 활용 가능.
“작은 RL 모델은 GPU 가 아니라 launch overhead 와 host-device 통신에 발목 잡힌다. 그 자리를 풀면 같은 hardware 가 10배 빠르다.” 학습 노트 · 재구성
§ 02RL 의 모델 크기 vs 환경 대수· small policy paradox
RL 의 throughput 은 “환경 대수 × env step 의 frequency”
supervised learning 의 throughput 단위는 tokens/sec. RL 은 environment steps/sec. 정책 모델이 작아도 환경이 느리면 학습이 느리고, 환경이 빨라도 정책이 작아서 GPU 가 비면 학습이 느리다.
supervised
큰 모델 + 큰 batch
- 모델 파라미터 7B+, batch 1M tokens
- 한 step 의 forward+backward = 100ms~1s
- GPU 활용률 80%+ 자연스러움
- 병목 = compute
RL on-policy (PPO)
작은 모델 + 작은 batch
- 정책 모델 1M~10M params
- 한 env step = 0.1~10ms (env 따라)
- 한 forward = 0.5~2ms — launch overhead 가 dominant
- 병목 = overhead, sync, env step
RL 의 결정적 차이
학습 한 step 안에 — (1) env step → (2) policy forward → (3) action 수행 → (4) reward 받기 → (5) gradient update — 5단계가 sequential 하게 묶여 있음. 대부분의 단계가 GPU 위에서 안 돌고 host 에서 돌면서 — host ↔ device 의 동기화가 매 step.
그래서 RL 의 GPU 활용률은 통상적으로 — single-env CPU 환경 (gym/MuJoCo) 에서 1~5%, vectorized CPU env (gym vector) 에서 5~15%, GPU env (IsaacGym) 에서 20~50%. LeanRL 의 목표는 마지막 카테고리에서 60~80% 까지 끌어올리는 것.
“supervised 와 RL 은 같은 GPU 를 쓰는 두 다른 게임이다. throughput 의 단위가 다르고, 병목의 자리가 다르고, 최적화 도구도 다르다.” 학습 노트 · 재구성
§ 03vectorized environment· environment 를 GPU 위에서
n=1 → n=4096 — 환경을 batch 로 만든다
단일 환경(env) 대신 수천 개 환경을 동시에 step. 각 환경의 state 가 batch dim 으로 묶여서 — policy forward 가 batch=4096 의 큰 op 이 됨. compute-bound 영역으로 진입.
vectorized env 의 두 종류.
- CPU vector env — gym.vector / SubprocVecEnv. n 개 process 가 병렬. host 에서 step, device 로 obs 전송. 여전히 host-device 통신 dominant.
- GPU vector env — IsaacGym, Brax, MuJoCo MJX. env 의 simulation 자체가 GPU 위에서. host-device 통신 거의 없음.
LeanRL 은 두 종류 모두 지원하지만 — 가장 큰 효과는 GPU env 와 결합할 때. CPU env 에서는 host-device transfer 가 launch overhead 만큼 dominant.
왜 GPU env 가 작은 모델의 RL 을 가능하게 하는가
모든 데이터 (observation, action, reward) 가 GPU 메모리에 살아 있음. host 에 한 번도 안 내려감. python interpreter 의 GIL 도 영향 거의 없음. RL 의 마지막 큰 sync 가 사라짐.
# LeanRL 의 일반 패턴 (의사코드)
import torch
import isaacgym as ig
env = ig.make_env("Cartpole", num_envs=4096,
device="cuda")
policy = MLP(obs_dim, act_dim).cuda()
policy = torch.compile(policy, mode="reduce-overhead")
for step in range(N):
obs = env.get_obs() # (4096, obs_dim) on cuda
action = policy(obs) # (4096, act_dim) on cuda
env.step(action) # env 시뮬레이션 GPU 위
rewards = env.get_rewards() # (4096,) on cuda
# gradient update — 같은 GPU 위에서
환경 수가 ~4096 정도 되면 — 모델 forward 가 batch 작아서 빠르고 + env step 이 GPU 에서 빠르게 — wall-clock 학습 시간이 single-env 의 100배 이상 빨라지는 사례도 있음. 강의에서 정확한 숫자를 언급했을 가능성 높음 (원본 영상 확인 필요).
§ 04actor-learner 구조· 두 thread 의 분리
data 수집과 gradient 업데이트를 분리한다
큰 RL 시스템 (IMPALA, SEED, A3C) 의 표준 구조 — actor 는 환경 위에서 trajectory 수집, learner 는 gradient update. 둘이 비동기로 돌아 — 한쪽이 다른쪽을 안 기다림. LeanRL 은 작은 모델 RL 에서도 같은 패턴을 쓴다.
FIG · actor-learner 의 비동기 흐름schematic
A
actor — env 위에서 step, action 수행, replay buffer 에 trajectory 추가. 정책 weight 는 learner 에서 가져온다 (느슨한 동기).
~5ms/step
B
buffer — replay buffer (off-policy) 또는 rollout buffer (on-policy). GPU 메모리 위 ring buffer.
— 0ms —
L
learner — buffer 에서 batch 샘플, forward + backward, 정책 weight 업데이트. learner 가 actor 보다 빠르거나 느릴 수 있음.
~10ms/step
∥
비동기 실행 — actor 와 learner 가 별도 thread / process / GPU stream 에서. host 의 GIL 영향 받지 않게 분리.
+++
두 흐름의 동기화 자리는 — (1) learner 가 update 한 weight 를 actor 가 가져갈 때 (loose), (2) actor 의 trajectory 를 buffer 에 쓸 때 (lock-free 가 좋음).
vectorized + actor-learner 가 합쳐지면
한 actor 가 4096 env 를 돌리고, 같은 시점에 별도 stream 에서 learner 가 gradient update. GPU 가 비는 시간이 거의 없음. 단점 — off-policy 의 staleness (오래된 데이터로 학습) 가 발생할 수 있음. 알고리즘 쪽에서 보정 (V-trace, IMPALA-style) 필요.
“actor-learner 는 system 의 결정 — 알고리즘이 staleness 를 처리할 수 있느냐의 trade-off 를 짊어지고 들어간다.” 학습 노트 · 재구성
§ 05GPU 자원 활용· launch overhead 의 자리
작은 모델의 한 forward = 50개 짜리 작은 kernel — 하나마다 launch
2-layer MLP 의 forward 도 — PyTorch 안에서는 50~100 개의 작은 op 으로 분해됨. linear, gelu, dropout, residual 등. 각자 GPU kernel launch 가 일어나고, 각 launch overhead 가 ~10μs. 모델 자체는 50μs 인데 launch overhead 가 500μs.
FIG · 작은 정책 모델의 한 forward 의 시간 분해schematic
eager → compile → cudagraph 누적 ~6.7배 throughput. 작은 모델에서 가장 큰 효과. 큰 모델은 kernel 자체 시간이 길어 cudagraph 효과 작음.
두 가지 도구의 의미.
- torch.compile — 50개 op 을 5~10개 fused kernel 로. launch 횟수 직접 감소. L053 참고.
- cudagraph — 그 fused kernel 들의 launch sequence 를 한 번 capture, 이후 “하나의 unit” 으로 launch. launch overhead 가 사실상 0.
두 도구가 결합되어야 가장 큰 효과. PyTorch 의 mode="reduce-overhead" 가 둘을 같이 적용.
cudagraph 의 RL 친화성
RL 학습은 — env 가 같은 batch size 로 step 하고, 정책 forward 도 같은 shape — cudagraph 의 “shape 고정” 요건이 자연스럽게 만족. supervised learning 의 가변 sequence 문제가 RL 에선 거의 없음. cudagraph 가 RL 에서 가장 잘 통하는 워크로드.
§ 06PyTorch 상의 구현· compile + cudagraph
LeanRL 의 의도된 단순성 — “PyTorch + 표준 도구”
LeanRL 의 디자인 철학은 단순함. JAX 나 Triton 으로 새 framework 를 짜는 게 아니라 — PyTorch 의 표준 도구 (compile, cudagraph) 를 “알맞게” 쓰는 것만으로 큰 효과. 사용자가 새 언어 안 배워도 됨.
torch.compile
정책/가치 함수 forward + loss 를 compile. mode="reduce-overhead" 로 cudagraph 같이.
vectorized env
IsaacGym, Brax, MuJoCo MJX 등 GPU env. n=1024~16384 정도.
replay buffer GPU
버퍼 자체를 GPU tensor 로. CPU 왕복 없음. ring buffer 패턴.
async actor-learner
두 stream 에서 비동기. weight 동기는 every k steps.
jax-style functional
policy 와 value 를 functional 형태로 — pure function. compile 친화적이고 vmap 가능.
CleanRL 호환
CleanRL 의 single-file 알고리즘 구현 스타일을 유지 — 한 파일에 PPO/SAC 전체.
왜 “Lean” 인가
코드 베이스가 작다는 의미. 한 알고리즘이 200~500 lines 안에 들어가도록 디자인. Stable Baselines 의 두꺼운 API 와 정반대 — 사용자가 자기 손으로 알고리즘을 수정하기 쉬움.
“LeanRL 은 새 패러다임이 아니다 — 이미 있던 PyTorch 도구를 RL workflow 에 맞게 잘 끼워 넣은 것이 본질.” 학습 노트 · 재구성
§ 07사례 결과· throughput 비교
LeanRL vs CleanRL vs Stable Baselines
정확한 벤치마크 숫자는 LeanRL repo 에 있지만 — 일반적 패턴은 “같은 알고리즘 (PPO 등) 을 같은 환경 (Cartpole, Humanoid) 에서 같은 hyperparam 으로 학습” 의 wall-clock 비교.
SB3
Stable Baselines 3 — 표준. CPU env (gym vector, n=16). 학습 wall-clock 의 baseline.
1× ref
CleanRL
CleanRL — single-file 구현. CPU env, n=4. SB3 보다 약간 빠름 (overhead 작음).
~1.2×
LeanRL CPU
LeanRL with CPU env — compile + cudagraph 만. CPU env 의 transfer 가 여전히 큼.
~3×
LeanRL GPU
LeanRL with GPU env (IsaacGym 등). 모든 도구 적용. GPU 60~80% 활용.
~30~100×
결정적인 도구는 GPU env
위 표에서 — compile + cudagraph 만으로는 ~3 배. 가장 큰 jump 는 “CPU env → GPU env” 의 단계. 이 의미는 — torch.compile 도 도움 되지만 RL 의 본질적 병목은 환경 시뮬레이션의 위치다.
강의에서 “speed of light” 라는 표현은 — RL 학습이 GPU 가 native 로 줄 수 있는 throughput 의 최대치에 도달한다는 의미. 그 자리에 도달하면 다음 병목은 알고리즘의 sample efficiency 가 됨 — “환경을 100배 빠르게 굴려도 학습 step 수가 같으면 똑같이 학습이 오래 걸린다”.
§ 08stable-baselines 와 비교· 기존 라이브러리
왜 SB3 위에서 안 짜고 LeanRL 을 따로 만들었나
Stable Baselines 3 는 RL 의 사실상 표준 — 알고리즘 구현이 검증되고, 사용자 base 가 큼. 하지만 GPU 활용 측면에서 — design 자체가 CPU env 시대에 맞춰져 있어서 새 도구 (compile, cudagraph) 가 잘 안 끼워짐.
Stable Baselines 3
- CPU env 가 default 가정
- 두꺼운 abstraction — Callback, Logger, Schedule
- 모든 알고리즘이 base class 상속
- 사용자가 알고리즘 수정 어려움
- compile / cudagraph 끼우기 비효율
- CPU 에서 학습 검증 단계 친화적
LeanRL
- GPU env 가 first-class
- single-file 알고리즘 (CleanRL 스타일)
- functional 형태 — torch.compile 친화
- 사용자가 한 파일을 자기 것으로 수정 가능
- compile + cudagraph default
- 학습 throughput 절대값 위주
LeanRL 의 위치는 — “SB3 를 대체” 가 아니라 “GPU env 시대의 best practice 를 합친 reference”. 기존 SB3 사용자는 그대로 유지, 새 시작은 LeanRL — 의 분기.
JAX 기반 RL (Brax, Mctx) 와의 차이
JAX 는 — 함수형 + JIT + vmap 으로 RL 에서 가장 빠른 구현 가능. 하지만 PyTorch 사용자가 JAX 로 옮기는 건 큰 비용. LeanRL 의 가치 — “PyTorch 안에서 JAX 수준의 throughput”. compile + cudagraph 가 JIT 의 기능을 대체.
§ 09다음 방향· multi-GPU · multi-task
single-GPU 의 sweet spot 을 넘어가는 자리
LeanRL 의 현재 sweet spot 은 single-GPU + small policy + GPU env. 이 자리를 넘어가면 — 더 큰 정책 (LLM-RL), multi-GPU (DDP), multi-task (population-based) 같은 새 도전.
- LLM-RL (RLHF, RLHF-PPO, GRPO) — 정책이 7B+ LLM. forward 가 100ms+ 라 launch overhead 무의미. cudagraph 효과 작음. compile 만으로 충분. 다른 차원의 도전 (memory, kv cache).
- multi-GPU PPO — actor 들을 각 GPU 에 분산. learner 가 한 곳에 모음. NCCL 통신 패턴 새로 디자인.
- population-based training — 여러 hyperparam set 의 정책을 동시 학습. 각 정책이 독립이라 GPU 활용 100% 가능.
- self-play — 정책이 자신을 상대로 학습. actor pool 의 latest weight vs old weight 의 동시 평가.
- continuous learning — 한 정책이 task 를 갈아타며 학습. catastrophic forgetting 의 인프라 차원 답.
LeanRL 의 future scope
repo 의 README 를 보면 — small policy + single GPU 를 first-class 로 두고, multi-GPU / LLM-RL 은 “future work”. 하지만 같은 인프라 패턴 (compile + cudagraph + GPU env) 이 다른 자리에서도 적용 가능. 원본 영상 확인 필요 — speaker 가 이 방향을 어떻게 봤는지.
“LeanRL 은 RL 의 모든 워크로드를 풀려는 도구가 아니다 — small-policy single-GPU 의 정확한 자리에서 가장 빠른 구현을 보이는 reference.” 학습 노트 · 재구성
§ 10기억할 메모와 자료· key takeaways
다시 열었을 때 5분 안에 손에 잡혀야 할 것
RL 의 throughput
env steps/sec. 모델 작아도 많은 env 가 같이 돌면 GPU 활용 ↑.
병목 셋
(1) launch overhead (작은 model), (2) host-device transfer (CPU env), (3) sync (actor-learner 단일 thread).
vectorized env
CPU vec (gym.vector) — 여전히 transfer 큼. GPU vec (IsaacGym, Brax) — 거의 zero transfer.
launch overhead 죽이기
torch.compile (fusion) + cudagraph (launch capture). PyTorch 의 mode="reduce-overhead".
actor-learner
data 수집 vs gradient update 분리. 비동기. weight 는 loose 동기.
LeanRL 의 디자인
PyTorch 표준 도구만 사용. single-file 알고리즘. functional policy. CleanRL 호환.
vs SB3
SB3 = CPU env 시대 표준, 두꺼운 abstraction. LeanRL = GPU env 시대 표준, lean 코드.
scope
small policy + single GPU 가 sweet spot. LLM-RL 과 multi-GPU 는 다른 도전.
§ 11다른 강의로 이어지는 길· connections
같은 자리를 다른 각도에서 다루는 강의들
§ 12열린 질문· open questions
원본 자막 실패 + speaker 정보 누락으로 비워둔 자리들
- speaker 정보 누락 — 강의 메타에 speaker 가 없음. LeanRL 은 PyTorch Labs 의 결과물이므로 — Vincent Moens, Albert Bou 등 contributor 중 한 명일 가능성. 원본 영상 확인 필요.
- 벤치마크 정확한 숫자 — “30~100배” 같은 추정값. 강의에서 정확한 비교 표가 등장했을 것이지만 본 노트는 일반적 패턴으로 재구성.
- 지원 알고리즘 목록 — PPO, SAC 외에 어디까지 LeanRL 이 구현했는지 — repo 에서 직접 확인 필요. DDPG, TD3, A2C 가능성.
- compile mode 의 정확한 선택 — “reduce-overhead” vs “max-autotune” 중 어느 쪽이 RL 워크로드에 권장인지.
- actor-learner 의 구현 디테일 — separate process 인지 same-process 별도 stream 인지. 두 패턴의 trade-off.
- replay buffer 의 GPU 구현 — ring buffer 의 정확한 패턴. lock 처리.
- algorithmic 보정 (V-trace 등) — actor-learner 의 staleness 를 어떻게 처리하는지 — algorithm 쪽의 변경 여부.
- JAX-RL 과의 직접 비교 — Brax + JAX 의 throughput 과 LeanRL 의 throughput — 비슷한 환경에서 어느 쪽이 빠른지.
검증 메모
본 노트의 throughput 비율 (1× / 1.2× / 3× / 30~100×) 은 일반적 RL 인프라의 직관적 수치. LeanRL 의 정확한 벤치마크는 repo 의 README 와 학회 발표를 직접 확인. 그리고 RL 알고리즘은 hyperparam 에 매우 민감 — throughput 외에도 sample efficiency 와 final return 의 비교가 같이 필요.