FlexAttention(Triton, torch.compile(dynamic=True)) 경로만 탄다. flash-attn 2.8.3은 설치돼 있지만 추론(attn_mode="flashattn")에서만 쓰이고, CUDA 커널 덤프에도 flash_fwd/bwd가 없다.q_varlen은 에피소드 1개를 그대로 reshape한 것이라 batch가 1로 고정 — 실측 이전까지 "packing이 flash를 탄다"는 전제 자체가 이 코드베이스에 해당하지 않았음을 확인.사용자 질문: "varlen packing이 실제로 flash 커널을 타는지, GPU당 몇 K 토큰까지 들어가는지, 스텝당 몇 초인지 실측했는지?" — 답은 실측한 적 없음이었다. 그동안 wan_va 학습 속도(4 GPU 19.2s/step, 8 GPU 34s/step)는 관측했지만, 그 시간이 attention 커널·GEMM·elementwise 중 어디에 쓰이는지, 그리고 GPU당 토큰 예산을 얼마나 쓰고 있는지는 블랙박스였다.
260907-lingbot_va_packing.html 참조)에 들어가기 전에 정량적 근거가 필요했다.wan_va/train.py에 opt-in 프로파일 훅(LINGBOT_PROFILE=<n>)을 추가: micro-step별 토큰 수·fwd+bwd 시간·peak 메모리를 기록하고, 마지막 micro-step에서는 torch.profiler로 CUDA 커널 표를 뽑는다. 로그인 노드 GPU 1장(FSDP 없음, bf16)에서 furniture_all_smoke(all_low 데이터, batch 1, 6 step)를 2회 실행 — 로그인 디버깅 범위(≤100 step, ≤10분) 내의 프로파일링 작업이라 sbatch 불필요.
| micro-step | latent (C,F,H,W) | 토큰 수 | fwd+bwd | peak mem |
|---|---|---|---|---|
| 0 (JIT 워밍업) | 48×240×8×16 | 9,152 | 38–76s | 44.7 GB |
| 1 (재컴파일) | 48×222×8×16 | 8,504 | 4–6s | 47.9 GB |
| steady | 48×115–123×8×16 | 4,652–4,940 | 0.85–0.96s | 79–81 GB |
| steady | 48×198×8×16 | 7,640 | 1.27s | 84.7 GB |
| steady | 48×237–240×8×16 | 9,044–9,152 | 1.62s | 86.4 GB |
| steady | 48×281–284×8×16 | 10,628–10,736 | 1.87–1.90s | 88.3 GB |
triton_tem_fused_zeros_1 133ms + triton_tem_fused_0 98ms (Inductor가 생성한 FlexAttention Triton 템플릿 fwd/bwd, 전체의 29%) / cuBLAS nvjet_* GEMM 3종 ≈200ms(25%) / elementwise 커널 ≈250ms(31%). flash_fwd/bwd 커널은 커널 표에 전혀 없음.분산 run과 대조: 4 GPU accum 10 = 19.2s/step → 에피소드당 1.9s(util 92–99%), 8 GPU accum 16 = 34s/step → 에피소드당 2.1s(util 50–59%). 1 GPU 실측과 같은 수준이라 FSDP 통신 자체는 부차적 원인이고, micro-step 단위가 작아서 생기는 dispatch/미융합 오버헤드가 본질임을 확인.
"packing이 flash 커널을 탄다"는 전제는 이 코드베이스에 해당하지 않는다 — FlexAttention Triton 커널이 돌고 있고, 애초에 에피소드 간 packing 자체가 없다(batch 1 고정). 유효 batch를 gradient accumulation으로만 키우는 현재 방식은 GPU당 토큰 예산의 1/8~1/10만 사용하므로, 에피소드 여러 개를 시퀀스 축으로 이어 붙이는 packing(FlexAttention mask_mod에 document id 추가 + collate에서 concat, GPU당 5–8 에피소드)을 구현하면 같은 유효 batch를 micro-step 1–2회로 처리할 수 있다는 정량적 근거를 확보했다. 토큰당 MFU가 7%로 낮은 편이라 packing으로 micro-step 수를 줄이면 dispatch 오버헤드 비중이 줄어 1.5–3× 속도 향상 여지가 있다고 판단(정확한 이득은 구현 후 실측 필요).
MFU 7%의 정확한 병목 분해(작은 GEMM vs elementwise 미융합 vs dispatch 오버헤드 중 어느 비중이 가장 큰지)는 이번 프로파일링만으로는 확정 못함 — CUDA 커널 표의 3분할(29%/25%/31%)은 대략적인 카테고리 추정치.
packing 구현: lerobot_latent_dataset collate에서 K개 에피소드 concat + per-token doc id, FlexAttnFunc block mask에 doc_id[q]==doc_id[k] 조건 추가, action/latent target도 concat. 로그인 스모크로 정합성(loss 동일) 확인 후 e128 재학습에 적용 — 실측 결과는 같은 날 후속 카드 lingbot_va_packing 참조(8 GPU 34→23s/step, 1.5×; 토큰당 계산은 15%만 개선되어 이득 대부분이 FSDP micro-step 동기화 감소 16→4회에서 나옴을 확인).