KV 캐시 블록 추정 트러블슈팅¶
kvcache_num_blocks를 지정하지 않으면 Optimum RBLN은 컴파일 완료 후 paged attention KV 캐시 크기를 자동으로 결정합니다. 이때 컴파일된 모델이 NPU DRAM을 모두 사용할 때까지 블록 pool을 확장합니다. 이 가이드에서는 Qwen3-8B Model Zoo 예제를 통해 memory_budget 옵션으로 이 자동 할당 크기를 제한하는 방법을 설명합니다. 이 옵션은 Optimum RBLN으로 컴파일하는 모든 decoder-only 모델에 동일하게 적용됩니다.
전제 조건
아래 측정값은 Qwen3-8B를 ATOM™-Max (RBLN-CA25) 4장에서 Model Zoo 기본 설정(max_seq_len=40_960, kvcache_partition_len=8_192)과 batch_size=8로 컴파일해 측정한 결과입니다. 블록 수는 모델, 컴파일 설정, NPU에 따라 달라지므로 이 값을 그대로 사용하기보다는 트레이드오프 경향을 파악할 수 있는 자료로서 참고해야 합니다.
rbln-smi로 호스트의 NPU를 확인하고, 하드웨어에 맞게 num_devices를 조정하세요.
요약¶
| 증상 | 근본 원인 | 해결 |
|---|---|---|
| 컴파일된 모델이 NPU 전체를 점유해 다른 모델을 올릴 여유가 없음 | 자동 블록 추정이 NPU DRAM을 모두 쓸 때까지 KV 캐시를 늘림 | Step 1 |
memory_budget을 지정한 뒤 Insufficient memory for the required KV cache |
memory_budget이 낮아 추정치가 그 설정에 필요한 최소 블록 수 아래로 내려감 |
Step 2 |
memory_budget ... exceeds the target NPU's available DRAM |
지정한 값이 NPU가 내주는 DRAM 용량보다 큼 | Step 3 |
memory_budget and an explicit kvcache_num_blocks are mutually exclusive |
두 값을 함께 지정했으나 추정은 블록 수가 비어 있을 때만 동작함 | Step 3 |
Step 1: 자동 KV 캐시 추정 제한하기¶
증상¶
모델 하나만 사용할 때는 컴파일과 추론 모두 정상적으로 동작하지만, 컴파일된 모델이 NPU 메모리 전체를 차지하게 됩니다. 이 경우 같은 NPU에 두 번째 모델이나 같은 파이프라인의 다른 submodule을 로드할 수 없고, 이후 batch 크기를 늘릴 여유 공간도 남지 않습니다.
근본 원인¶
kvcache_num_blocks의 기본값은 0이며, 이는 KV 캐시 크기를 컴파일 후에 자동으로 결정한다는 의미입니다. 이때 Optimum RBLN은 NPU DRAM 용량을 상한으로 삼아 할당 가능한 최대 크기의 블록 pool을 탐색합니다. 컴파일된 모델 자체가 사용하는 메모리를 제외한 나머지 공간을 전부 KV 캐시에 할당하기 때문에, 다른 모델을 추가로 올릴 여유 공간이 남지 않습니다.
기준 설정에서 이 탐색은 최대 블록 수인 40블록에서 끝나며, NPU 4장 각각에 11.25 GB의 KV 캐시를 예약합니다.
해결¶
KV 캐시 크기를 자동으로 결정할 때 사용할 DRAM 용량을 memory_budget으로 제한합니다.
memory_budget은 NPU 1장 단위로 적용되며, 그 NPU가 실제로 내주는 DRAM 용량을 기준으로 해석됩니다. ATOM™-Max (RBLN-CA25)는 시스템 예약분을 제외하고 16,877,879,296 바이트(15.72 GB)를 내주며, rbln-smi가 보고하는 전체 메모리 값이 바로 이 용량입니다.
memory_budget은 세 가지 형태를 받습니다.
| 형태 | 예 | 의미 |
|---|---|---|
| 비율 | 0.5 |
NPU가 내주는 DRAM의 절반. (0, 1] 범위의 float이며 권장하는 형태입니다. |
| 퍼센트 문자열 | "50%" |
0.5와 동일합니다. 값이 커맨드라인을 거쳐 전달될 때 편리합니다. |
| 바이트 수 | "8GB", "512MB", 8 * 2**30 |
용량을 직접 지정합니다. 단위는 이진(KB = 1024 바이트이며 TB까지)이고 대소문자를 구분하지 않으며, 단순 int는 바이트 수입니다. |
memory_budget은 KV 캐시에만 적용되는 값이 아니라 컴파일된 모델이 NPU에 올리는 모든 것에 적용됩니다. 가중치와 workspace를 먼저 차감하고 남은 공간을 KV 캐시가 차지하기 때문에, KV 캐시의 블록 수는 memory_budget보다 더 가파르게 줄어듭니다. 위 예제에서 memory_budget만 바꿔 보면 다음과 같습니다.
memory_budget |
추정된 kvcache_num_blocks |
NPU당 KV 캐시 |
|---|---|---|
| 미지정 | 40 | 11.25 GB |
0.9 |
37 | 10.41 GB |
0.8 |
31 | 8.72 GB |
"12GB" |
29 | 8.16 GB |
0.7 |
25 | 7.03 GB |
0.6 |
20 | 5.62 GB |
"8GB" |
15 | 4.22 GB |
0.5 |
14 | 3.94 GB |
0.4 |
9 | 2.53 GB |
확정된 블록 수는 저장된 산출물에서 확인합니다.
값이 0이면 추정이 동작하지 않은 것이며, 블록 수를 명시해 컴파일한 경우입니다. Step 3을 참고하세요.
같은 옵션을 컴파일 CLI에서도 쓸 수 있으며, 세 가지 형태가 모두 동작합니다.
Step 2: memory_budget을 최소 블록 수 위로 유지하기¶
증상¶
memory_budget을 너무 낮게 잡으면 컴파일이 다음 에러로 실패합니다.
근본 원인¶
블록 pool이 일정 크기 아래로 내려가면 시퀀스 하나를 온전히 담을 수 없고 batch의 각 항목에 블록을 하나씩 나눠 줄 수도 없습니다. 그래서 Optimum RBLN은 더 작은 pool로 물러서지 않고 추정 결과를 거부합니다. flash attention에서 하한과 최대 블록 수는 다음 식으로 정해집니다.
+ 1은 시퀀스가 계속 길어지는 동안 블록 테이블의 빈 슬롯을 채우기 위한 여분 블록으로, 두 항 중 어느 쪽이 하한이 되든 항상 필요합니다.
여기서 kvcache_block_size는 kvcache_partition_len과 같습니다. 기준 설정의 시퀀스 항은 5블록인데 batch_size=8이 이를 8블록으로 끌어올리므로 하한은 9블록이고, 최대 블록 수는 40블록입니다. 0.4는 9블록으로 하한과 정확히 같고, 0.3은 3블록으로 추정되어 위 에러로 거부됩니다.
memory_budget을 낮출 수 있는 폭은 이 두 값의 간격에서 나오고, 그 간격은 batch_size가 벌립니다. batch 항목이 하나 늘 때마다 최대 블록 수는 시퀀스 하나 분량만큼 커지는데, 하한은 두 항 중 큰 쪽만 따라가기 때문입니다. 같은 설정에서 batch_size=1이면 최대 블록 수와 하한이 모두 5블록으로 같아지므로, 최대 블록 수에 못 미치는 값은 어느 것도 통과하지 못합니다.
해결¶
추정치가 하한을 넘길 때까지 memory_budget을 올린 뒤, Step 1처럼 확정된 블록 수를 확인하세요. 하한 때문에 memory_budget을 더 낮출 수 없다면 max_seq_len을 줄이세요. max_seq_len을 낮추면 하한도 함께 내려가므로 시퀀스 하나가 예약하는 양 자체가 줄어듭니다.
| 변경 | memory_budget 조정 폭에 미치는 영향 |
|---|---|
batch_size 상향 |
하한과 최대 블록 수의 간격이 넓어져 조정 폭이 커집니다 |
max_seq_len 하향 |
하한과 최대 블록 수가 함께 내려가 같은 DRAM으로도 시퀀스를 담을 수 있습니다 |
kvcache_partition_len 하향 |
하한의 시퀀스 항은 올라가지만 블록 하나의 크기가 작아집니다 |
Step 3: memory_budget 설정 오류 해결하기¶
증상¶
두 가지 검증 에러 중 하나가 발생합니다.
근본 원인¶
바이트로 지정한 값이 대상 NPU가 내주는 DRAM 용량을 넘으면 첫 번째 에러가 발생합니다. 그 용량은 Step 1에서 본 것처럼 기준 NPU에서 16,877,879,296 바이트(15.72 GB)입니다. 이보다 큰 값은 장치에 없는 용량을 요구하는 셈이므로 조용히 잘라내지 않고 거부합니다.
두 번째 에러는 자동 추정이 무력화되는 조합을 막습니다. memory_budget은 자동 추정이 쓰는 값이고, 자동 추정은 kvcache_num_blocks가 비어 있을 때만 동작합니다. 두 값을 함께 지정하면 추정을 건너뛰면서 memory_budget이 조용히 무시되므로, 설정 시점에 조합 자체를 거부합니다.
해결¶
산출물을 여러 환경에서 쓸 예정이라면 바이트 수보다 비율로 지정하세요. 비율은 컴파일 대상 NPU에 맞춰 해석됩니다. 바이트로 지정한다면 대상 NPU가 내주는 DRAM 용량 아래로 유지하세요.
두 제어 수단 중 하나만 선택합니다.
| 목적 | 지정할 값 |
|---|---|
| 메모리 상한 안에서 블록 수를 추정에 맡김 | memory_budget |
| 블록 수를 정확히 고정 | kvcache_num_blocks |
Note
memory_budget은 컴파일 시점 입력이라 rbln_config.json에 기록되지 않습니다. 산출물에는 확정된 kvcache_num_blocks만 남으며 추론은 그 값을 읽습니다. memory_budget을 바꾸려면 다시 컴파일해야 합니다.