요약. vLLM V1 은 우리가 4 가지 문제를 해결한 후 vLLM V0 의 참조 결과와 일치했습니다:
- 처리된 rollout logprobs (롤아웃 로그확률)
- V1 전용 런타임 기본값
- 비행 중 weight-update 경로
- fp32
lm_head (최종 투영에 사용됨)
우리는 RL objective(강화학습 목표) 를 변경하기 전에 backend behavior(백엔드 동작) 를 먼저 수정했습니다.
참조 실행은 vLLM 0.8.5를 사용했고, V1 실행은 vLLM 0.18.1을 사용했습니다. Figure 1 은 최종 결과를 보여줍니다. 빨간색 실행은 초기 V1 시도이고, 초록색 실행은 아래에서 설명한 수정 후 최종 V1 실행입니다.
vLLM V1 은 V0 엔진의 상당한 재작성입니다. 따라서 우리의 마이그레이션 목표는 의도적으로 좁았습니다:
- V1 이 훈련기 (trainer) 가 기대하는 형태로 rollout logprobs 를 반환하는지 확인
- 동일한 워크로드를 V0 참조에 대해 다시 실행
- 백엔드 패리티가 회복된 후에만 objective-level(목표 수준) 변경 평가
첫 번째 눈에 띄는 증상은 다음과 같습니다:
clamp_log_ratio_new_old_indicator
kl_new_old
entropy
reward
이 지표들은 이 실험에 사용된 GSPO 훈련 실행에서 나왔습니다. PPO, GRPO, 또는 rollout-side logprobs 를 최적화 목표의 일부로 취급하는 온라인 RL 시스템 모두에서 동일한 불일치 클래스가 나타날 수 있습니다.
초기 V1 실행은 문제를 명확하게 보여줍니다. 훈련기-side logprobs 와 reward 는 훈련 초기에 V0 참조로부터 멀어집니다.
동일한 패턴이 훈련기 지표에서도 나타납니다. Clip rate(클립 비율) 은 초기 비교에서 가장 읽기 쉬운 신호입니다.
우리는 가능한 원인을 3 가지 레이어로 분리했습니다:
Semantic mismatch: 백엔드가 훈련기가 기대하는 것과 다른 의미로 logprobs 를 반환합니다.Inference-path mismatch: 백엔드가 캐싱, 스케줄링, 또는 요청 처리에 대해 다른 런타임 기본값을 사용하므로 동일한 프롬프트는 다른 실행 경로를 따릅니다.Objective mismatch: RL objective(강화학습 목표) 는 남아있는 staleness(오래된 데이터) 또는 백엔드 불일치에 대한 수정이 필요합니다.
우리는 초기에 제 3 범주를 너무 일찍 의심했습니다. 유용한 진단은 첫 두 가지를 backend behavior problem(백엔드 동작 문제) 로 취급하고 먼저 제외하는 데서 나왔습니다.
첫 번째 문제는 세미antik적 (semantic) 입니다. vLLM V1 은 기본적으로 로우 모델 출력에서 logprobs 를 반환하며, temperature scaling(온도 스케일링), penalties(벌칙), top-k/top-p 필터링과 같은 logits post-processing(로짓 후처리) 전에 있습니다. PipelineRL 이 기대하는 것은 샘플러가 사용하는 처리된 분포의 logprobs 입니다.
필요한 설정은 다음과 같습니다:
logprobs-mode=processed_logprobs
이것은 rollout logprobs 의 명확한 평균 오프셋을 제거했습니다. 훈련 곡선은 여전히 알려진 좋은 참조에 대한 간극을 보여주었으므로, 다음 문제는 인프러런스 경로에 있었습니다.
Policy-ratio(정책 비율) 플롯은 이를 직접 보여줍니다. V1 에서 processed_logprobs가 켜지면, 모든 3 개의 실행에서 평균 정책 비율은 1.0에 매우 가깝게 중심에 유지됩니다. 이는 mean-bias(평균 편향) 수정을 확립합니다. 나머지 불일치는 clip rate, KL, entropy 및 downstream training behavior(다운스트림 훈련 동작) 에서 나타납니다.
초기 V1 실행은 엔진 버전과 V1 런타임 기본값을 혼합했습니다:
- prefix caching: 초기 실행에서 명시되지 않았으므로 vLLM
0.18.1의 기본값이 적용됨 - async scheduling: 초기 실행에서 명시되지 않았으므로 vLLM 0.18.1의 기본값이 적용됨 - ad-hoc disable-cascade-attn: 런타임 kwarg passthrough 를 통해 설정된 오버라이드이며, 커밋된 구성의 패리티 레시피에 속하지 않습니다
패리티 실행을 위해 우리는 다음과 같은 선택을 명시했습니다:
vllm_config:
use_v1: true
vllm_kwargs:
...
Prefix caching 는 별도의 주의를 필요로 합니다. 이는 일반적으로 고정된 모델 상태에서 정확성을 유지하는 추론 최적화입니다. 이 온라인 RL 설정에서는 V1 의 경우 V0 참조 경로에 비해 캐시 수명과 재사용의 차이였습니다. 또한 actor 는 반복되는 프록시, 동시 요청, 비동기 스케줄링 및 진행 중인 가중치 업데이트를 처리했습니다.
프록시 캐시 히트는 캐시 정책이 가중치 업데이트 경계를 무시할 경우, 가중치 업데이트 전에 계산된 상태를 재사용할 수 있습니다. 프록시 캐시를 비활성화하면 패리티 비교에서 V1 만의 자유도를 하나 제거했습니다.
가중치 동기화 또한 온라인 RL 업데이트 모델과 일치해야 했습니다. 하나의 옵션은 V0 보다 V1 을 더 엄격하게 만들어, 각 업데이트마다 요청을 배출하고 캐시를 초기화하는 것입니다. 이는 별도의 질문을 답변합니다. 우리는 먼저 V1 이 기존 V0 동작과 일치할 수 있는지 확인해야 했습니다.
V0 가 실제로 수행한 것은 다음과 같습니다:
- 엔진 경계에서 실행을 차단
- 새로운 가중치를 로드
- 명시적인 캐시 상태 무효화 없이 재개
가장 가까운 V1 유사체는 다음과 같습니다:
await engine.pause_generation(mode="keep", clear_cache=False)
await engine_client.collective_rpc_async(
"receive_weight_update",
...
두 가지 세부 사항이 중요합니다:
mode="keep"
이는 wait 또는 abort 보다 오래된 진행 중인 업데이트 모델과 더 잘 맞습니다.
clear_cache=False
이는 V0 래퍼 동작을 따르며, 업데이트 시 캐시 상태를 그대로 두었습니다.
지연은 유용한 런타임 진단입니다. 초기 V1 경로는 훈련 후반에 더 많은 지속적 지연을 가집니다.
위 V1 백엔드 수정은 명백한 마이그레이션 문제를 제거했지만, 최종 패리티는 로짓을 계산하는 수치 경로를 일치해야 했습니다. 트레이너는 최종 투영에 fp32 lm_head 를 사용했습니다. 롤아웃 백엔드는 해당 동작을 일치해야 했습니다.
밀접하게 관련된 문제는 MiniMax-M1 기술 보고서에서 나타납니다: 그들의 RL 실행은 훈련/추론 토큰 확률 불일치를 보였으며, 이는 LM 출력 헤드로 추적되었고 fp32 로 헤드를 계산하여 수정했습니다.
이것은 중요합니다. RL 업데이트는 토큰 로짓을 직접 소비하기 때문입니다. 로짓의 작은 변화는 정책 비율, KL, 및 클립에서 볼 수 있습니다. 따라서 최종 투영 정밀도는 온라인 RL 의 정확성 표면의 일부입니다. ScaleRL 논문은 나중에 fp32 로짓/헤드 계산을 RL 레시피의 일부로 포함하고, 대규모 RL 에 유용한 설계 선택으로 아블레이션합니다.
fp32 lm_head 경로를 포함하면 보상이 최종 패리티 결과를compact하게 보여줍니다. Figure 6 에서 최종 V1 실행은 V0 참조를 추적하며, 초기 V1 시도는 명확히 다른 보상 곡선을 생성합니다.
부정적인 결과는 중요합니다. 이는 일반적인 설명을 배제하기 때문입니다:
- 의미론적 로짓 확률 버그 수정; 훈련 불일치가 남았습니다.
- Batch invariance: 불일치는 별도의 테스트에서 남아있으며, 더 높은 지연, 더 높은 클립 비율 및 NCCL 문제가 있었습니다.
- 첫 번째 V1 실행을 공정한 기준선으로 간주: 첫 번째 V1 실행에는 여러 V1 만 기본값이 활성화되어 있어 혼란스러운 마이그레이션 비교였습니다.
측정 측면의 수정 도구인 절단된 중요성 샘플링, 중요 비율 재가중치화 및 관련 방법은 유용한 도구입니다. 만약 롤아웃 의 의도적陈旧, 비동기 생성 또는 트레이너 측 정책과 동등성이 없는 백엔드에서 생성되었다면, 어떤 형태의 수정을 추가하는 것이 종종 올바른 것입니다.
이 문제의 첫 번째 문제는 추론 (inference) 정확도였습니다. V1로 이동한 후 rollout 백엔드는 logprobs 와 런타임 동작을 반환하여 트레이너 가정을 깨뜨렸습니다. 해당 시점에 객체 측 수정을 추가하면 두 가지 질문이 혼동됩니다:
- 추론 백엔드가 올바른 logprobs 를 생성하는가?
- 올바른 logprobs 가 주어졌을 때, 여전히 오프-폴리시 (off-policy) 또는 비동기 (async) 수정이 필요한가?
이러한 질문들을 분리해야 합니다. 그렇지 않으면 객체 측 수정은 잘못된 추론 백엔드 동작을 보상할 수 있어 학습 곡선을 해석하기 어렵게 만듭니다.
현재 객체는 여전히 개선될 수 있습니다. 추론 패리티 (inference parity) 가 복원된 후 다음 개선 사항은 일반적인 비동기/오프-폴리시 정리입니다:
- rollout 시간의 명시적 행동-폴리시 (behavior-policy) logprobs 를 유지
- 최적화 시 트레이너 측 오래된 정책 (old-policy) logprobs 를 재계산
- 백엔드 불일치 수정을 정책 업데이트 비율 (policy-update ratio) 과 분리
- ESS 와 같은 진단 정보를 객체 측 수정 항과 함께 종합 트레이너 지표와 함께 추적
이 마이그레이션의 주요 교훈은 더 좁습니다: 먼저 백엔드 정확도를 수정한 후, 여전히 남는 불일치를 위한 수정을 추가하세요.