# GLM-5 대규모 서비스 중 발견한 레이스 컨디션 버그 수정기 — Coding Agent 추론 인프라의 Scaling Pain

> Clean Markdown view of GeekNews topic #29032. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=29032](https://news.hada.io/topic?id=29032)
- GeekNews Markdown: [https://news.hada.io/topic/29032.md](https://news.hada.io/topic/29032.md)
- Type: news
- Author: [darjeeling](https://news.hada.io/@darjeeling)
- Published: 2026-04-30T10:40:16+09:00
- Updated: 2026-04-30T10:40:16+09:00
- Original source: [z.ai](https://z.ai/blog/scaling-pain)
- Points: 2
- Comments: 1

## Topic Body

GLM-5 기반 Coding Agent를 수억 건 규모로 서비스하며 마주친 KV Cache 레이스 컨디션 버그 두 건의 재현·수정 과정과 처리량 개선 최적화를 공유한다.  
  
  
#### 배경  
  
스케일링 법칙(Scaling Laws)은 모델 파라미터와 데이터 규모의 혁신만 이끈 게 아니라, 인프라 엔지니어링도 한계까지 밀어붙이고 있다. Z.ai는 이 과정에서 생기는 부작용을 **Scaling Pain**이라 부른다.  
  
GLM-5 시리즈로 복잡한 Coding Agent 워크로드를 하루 수억 건 처리하던 중, 일부 사용자에게서 **깨진 출력(garbled output), 반복 생성, 희귀 문자 생성** 등의 이상 현상이 보고됐다. 이 문제들은 표준 추론 환경에서는 전혀 재현되지 않고, **고동시성·장문맥 환경에서만** 나타났다.  
  
---  
  
#### 핵심 결과 요약  
  
| 항목 | 수치 |  
|---|---|  
| Bug Fix #1 적용 후 이상 출력 비율 | 0.1% → 0.03% 미만 |  
| LayerSplit 처리량 개선 (40K~120K 토큰) | **+10% ~ +132%** |  
| HiCache fix는 SGLang PR #22811로 기여 | ✅ |  
  
---  
  
#### 이상 현상 탐지: Speculative Decoding 지표 활용  
  
이상 현상을 자동으로 감지하는 것 자체가 난제였다. 정규식 같은 휴리스틱은 오탐·미탐이 많고, 모델 기반 분류기는 대규모 실험에 비용이 너무 컸다.  
  
돌파구는 **Speculative Decoding 메트릭**이었다.  
  
- **깨진 출력 / 희귀 문자**: `spec_accept_length`가 극단적으로 낮음 → draft 모델과 target 모델의 KV Cache 상태 불일치 신호  
- **반복 생성**: `spec_accept_rate`가 극단적으로 높음 → 손상된 KV Cache로 인해 어텐션 패턴이 반복 루프로 수렴하는 신호  
  
이를 바탕으로 온라인 모니터링 전략을 구현했다. 생성 토큰 128개 초과 시점에 `spec_accept_length < 1.4` 또는 `spec_accept_rate > 0.96`이면 즉시 생성을 중단하고 로드밸런서에 재시도를 넘긴다. Speculative Decoding이 **성능 최적화 도구에서 출력 품질 실시간 모니터링 도구**로 확장된 셈이다.  
  
---  
  
#### Bug Fix #1: PD 분리 아키텍처의 KV Cache 레이스 컨디션  
  
##### 원인  
  
PD(Prefill-Decode) 분리 아키텍처에서 꼬리 지연(tail latency) 제어를 위해 타임아웃 기반 요청 중단 메커니즘을 운용하고 있다. Prefill이 정해진 시간 내에 완료되지 않으면 Decode 측이 해당 요청을 abort하고 KV Cache를 회수한다.  
  
문제는 **abort 신호가 Prefill 측에 제대로 전달되지 않는다**는 것이다. Decode가 KV Cache를 회수해 새 요청(Req2)에 재할당한 뒤에도, 이전 요청(Req1)의 RDMA write와 Prefill 연산이 계속 진행되어 **Req2의 KV Cache를 덮어쓰는** 현상이 발생했다.  
  
##### 수정  
  
Decode가 abort를 발행한 뒤 Prefill 측에 알림을 전송하고, Prefill이 다음 두 조건 중 하나를 만족할 때만 **"회수 안전" 신호**를 반환하도록 변경했다.  
  
1. RDMA write가 아직 시작되지 않은 경우  
2. 이미 발행된 write가 모두 완료된 경우  
  
Decode는 이 확인을 받은 후에만 KV Cache를 재사용한다. 적용 결과 이상 출력 비율이 **0.1% → 0.03% 미만**으로 감소했다.  
  
---  
  
#### Bug Fix #2: HiCache의 Load-Use 순서 보장 누락  
  
##### 원인  
  
Coding Agent 워크로드는 평균 입력 길이가 70K 토큰을 넘고 prefix 재사용률이 높다. 이를 위해 **HiCache(계층적 KV Cache)** 를 운용하는데, CPU 메모리에서 KV Cache를 비동기로 스왑인하면서 `Load Stream`과 `Forward Stream`을 겹쳐 실행하는 구조다.  
  
문제는 Indexer 커널이 **Indexer cache 로드 완료와의 동기화 제약을 명시하지 않았다**는 점이다. Forward Stream이 Load Stream보다 먼저 실행을 시작하면, 아직 로드되지 않은 KV Cache를 읽는 **read-before-ready** 패턴이 발생해 이상 출력으로 이어졌다.  
  
##### 수정  
  
Indexer 커널 실행 전에 Load Stream과의 **명시적 동기화 포인트**를 삽입, 데이터 준비 완료 후에만 Forward Stream이 계산을 진행하도록 변경했다. 이 수정은 **SGLang 커뮤니티에 PR #22811로 기여**됐다.  
  
---  
  
#### 최적화: LayerSplit (레이어 단위 KV Cache 분산 저장)  
  
두 버그의 공통 병목은 Prefill 단계 자체의 부하였다. 이를 근본적으로 개선하기 위해 **LayerSplit**을 설계·구현했다.  
  
기존에는 Context Parallelism(CP) 환경에서 각 GPU가 모든 레이어의 KV Cache를 중복 저장했다. LayerSplit에서는 각 GPU가 **레이어의 일부만** 담당하도록 분산 저장하여 GPU당 메모리 사용량을 크게 줄인다.  
  
실행 시에는 해당 레이어의 KV Cache를 소유한 CP rank가 어텐션 연산 전에 캐시를 브로드캐스트한다. 브로드캐스트와 indexer 연산을 겹쳐 실행하여 통신 오버헤드를 숨겼으며, 추가 통신 데이터는 indexer cache(KV Cache의 약 1/8 크기)뿐이라 전체 오버헤드는 무시할 수준이다.  
  
90% 캐시 히트율 조건에서 40K~120K 토큰 요청에 대해 처리량이 **10%~132% 향상**됐으며, 컨텍스트 길이가 길수록 개선 폭이 커진다.  
  
---  
  
#### 결론  
  
> "처리량, 지연, 가용성만으로는 부족하다. 시스템은 모든 생성 요청 뒤에서 모델 상태의 **정확성**도 보장해야 한다. 스케일링 법칙이 능력을 밀어붙이지만, 그 능력을 대규모에서 신뢰할 수 있게 만드는 것은 철저한 시스템 엔지니어링뿐이다."  
  
---  
  
*출처: Z.ai Research Blog (2026-04-30)*

## Comments



### Comment 56592

- Author: darjeeling
- Created: 2026-04-30T10:51:32+09:00
- Points: 1

PR LINK https://github.com/sgl-project/sglang/pull/22811
