Repository navigation
fix: v4.1.2 hotfix - KV cache at batch >= 2, TP/DP checkpoint names, MPS daemon scope - #190
Merged
Merged
Conversation
The exported graph ties position_ids' batch dim to input_ids'. Prefill passed position_ids [1, S] and decode [1, 1], and decode fed the [B] sampled tokens as [1, B]. Prefill now builds [B, S] positions, decode [B, 1] positions and a [B, 1] token input. Adds tests/test_kv_cache_batch.py: greedy KV-cache generation matches HF at B=1 and B=2 (GPU only). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit d46b8ff)
save_ckpt named files by pipeline stage only, so with tp > 1 the TP
ranks overwrote each other's shards, and all DP replicas wrote and
pruned the same files. save_lora_ckpt already named TP shards but let
every DP replica write. Following save_hf_ckpt, only DP rank 0 writes
and save_ckpt/load_ckpt add a _tp{rank} suffix when tp > 1 (PP-only
names unchanged). The checkpoint directory no longer becomes
checkpoint_None_<stage> without a postfix (the "or" fallback never
triggered).
Adds tests/test_ckpt_names.py.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit fb09a61)
) _mps_daemon_running fell back to a host-wide pgrep, so another job's MPS daemon (other pipe directory) looked like ours; the health probe on our pipe dir then failed and the stale cleanup ran pkill -u $UID on every MPS server and control process, killing the other job's daemon. Liveness is now our control socket only, and the stale cleanup sends quit to our pipe dir and removes our socket, without pkill. Adds tests/test_mps_manager.py with a fake pipe dir. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 0e69cc9)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
배경
v4.1.1(
62a7831)에서 아래 세 결함이 재현됩니다. 세 결함 모두 optimus-rm에서는 이미 고쳤고(#187, #188, #189), 이 PR은 그 세 커밋을 main에 그대로 cherry-pick한 것입니다(cherry picked from commit ...표시 포함). main 사용자를 위한 v4.1.2 핫픽스용입니다.재현과 검증은 v4.1.1이 명시한 지원 조합(
opt_prime/README.md: PyTorch 2.5.0 / CUDA 12.4,transformers==4.46.2)에서 했습니다. 환경은 Python 3.10,torch 2.5.0+cu124,transformers 4.46.2, A100 80GB 한 장입니다.1. KV 캐시 생성이 배치 크기 2 이상에서 크래시 (#164, 원본
d46b8ff)문제
Optimus_Inference(..., use_kv_cache=True, dynamo_capture=True)로generate()를 부르면 배치 크기 1에서는 HF greedy와 같은 결과가 나옵니다.RuntimeError: mat1 and mat2 shapes cannot be multiplied (2x128 and 64x64)로 크래시합니다.원인
position_ids의 모양이[1, S]입니다. 그런데 torch.export로 캡처한 그래프는position_ids의 배치 차원을input_ids([B, S])와 같은 크기로 묶어 둡니다.position_ids를[[position]]([1, 1])로 만듭니다.next_token.unsqueeze(0)이라[B]가[B, 1]이 아니라[1, B]가 됩니다.수정 (
inference.py,schedule_infer.py, +5/−7줄)torch.arange(seq_len).expand(B, -1)로[B, S]를 만듭니다.torch.full((B, 1), position)으로[B, 1]을 만듭니다.unsqueeze분기 세 줄을next_token.reshape(-1, 1)한 줄로 바꿉니다.테스트:
tests/test_kv_cache_batch.pygenerate()greedy 출력과 토큰 단위로 같은지 비교합니다.2. TP/DP rank의 체크포인트가 서로 덮어씀 (#165, 원본
fb09a61)문제
save_ckpt()는 파일 이름을 pipeline stage로만 정합니다(ckpt_step_{step}_epoch_{epoch}.pt).os.remove가FileNotFoundError를 낼 수 있습니다.save_lora_ckpt()도 DP replica마다 저장합니다.ckpt_dir_postfix를 주지 않으면 디렉터리 이름이checkpoint_None_<stage>가 됩니다.f"checkpoint_{postfix}_{stage}" or f"checkpoint_{stage}"에서 왼쪽 문자열이 항상 참이라,or오른쪽 기본값이 한 번도 쓰이지 않습니다.수정 (
opti_pri.py, +13/−4줄)save_ckpt와save_lora_ckpt는 DP rank 0만 저장합니다((rank // tp) % dp == 0). 이미save_hf_ckpt가 쓰는 방식입니다._tp{rank % tp}를 붙입니다. 오래된 파일을 지울 때도 자기 TP shard의 파일만 지웁니다.load_ckpt는 같은 이름 규칙으로 읽습니다.checkpoint_<stage>입니다.테스트:
tests/test_ckpt_names.py3. MPS 매니저가 같은 사용자의 다른 GPU 작업 데몬을 죽임 (#166, 원본
0e69cc9)문제
_mps_daemon_running()은 우리 pipe 디렉터리에control소켓이 없어도, 호스트 전체에서pgrep nvidia-cuda-mps-server/control이 하나라도 걸리면 "실행 중"으로 판단합니다._force_cleanup_stale_daemon()을 부르고, 이 함수가pkill -u $UID로 그 사용자의 MPS server와 control 프로세스를 전부 죽입니다./tmp/mps-a로 MPS를 쓰는 중에 작업 B가 기본 디렉터리로 시작하면, 작업 A의 MPS 데몬이 죽습니다.수정 (
mps_manager.py, +8/−38줄)control소켓만으로 판단합니다. 호스트 전체를 보는pgrep검사를 지웁니다.pkill루프를 지웁니다. 우리 pipe 디렉터리에quit를 보내고, 우리 소켓만 지웁니다.테스트:
tests/test_mps_manager.pysubprocess.run을 바꿔치기해 "다른 작업의 데몬이 떠 있는" 상황을 만듭니다.pkill이 호출되지 않는지 확인합니다.검증
명령:
cd opt_prime && TORCH_DEVICE_BACKEND_AUTOLOAD=0 CUDA_VISIBLE_DEVICES=<GPU> PYTHONPATH=$PWD python -m pytest -q -rA tests환경:
torch 2.5.0+cu124,transformers 4.46.2, A100 80GB 한 장.62a7831에 테스트 파일만 추가torch 2.10.0+cpu): 7 passed, 2 skipped. KV 테스트만 skip됩니다.호환성과 제한
checkpoint_None_<stage>입니다. 이 PR 이후에는checkpoint_<stage>를 찾으므로, 그런 체크포인트로 재개하려면 디렉터리 이름을 바꿔야 합니다. PP만 쓰는 경우 파일 이름은 바뀌지 않습니다._tp{rank}가 붙습니다. 그 전 파일은 shard 하나가 이미 사라진 상태라 원래부터 제대로 복원할 수 없었습니다.quit에 응답하지 않고 멈춰 있어도 더는 강제로 죽이지 않고, 새 데몬을 띄웁니다.dynamo_capture=False)로 KV 캐시를 켜면, 배치 크기와 상관없이 tracing 단계에서NotImplementedError: argument of type: <class 'transformers.utils.fx.ProxyableDynamicCache'>로 실패합니다. 이 PR 전후 동작이 같은 별개 문제라 이 PR에서는 다루지 않습니다.opt_prime/tests에 이 세 테스트만 생깁니다.관련 Issue
Refs #164, #165, #166 (optimus-rm에서 #187, #188, #189로 수정, 이 PR은 main 백포트)
🤖 Generated with Claude Code