GLM-5 आधारित Coding Agent को रोज़ाना सैकड़ों मिलियन रिक्वेस्ट के पैमाने पर सर्व करते हुए सामने आए KV Cache race condition bug के दो मामलों की पुनरुत्पादन·सुधार प्रक्रिया और throughput सुधार optimization साझा किए गए हैं.
पृष्ठभूमि
Scaling Laws ने केवल model parameters और data scale में नवाचार को आगे नहीं बढ़ाया, बल्कि infrastructure engineering को भी उसकी सीमा तक धकेल दिया है. Z.ai इस प्रक्रिया में पैदा होने वाले side effects को Scaling Pain कहता है.
GLM-5 series के साथ जटिल Coding Agent workload को प्रतिदिन सैकड़ों मिलियन बार प्रोसेस करते समय, कुछ users से garbled output, repeated generation, rare character generation जैसी असामान्य घटनाओं की रिपोर्ट मिली. ये समस्याएँ standard inference environment में बिल्कुल reproduce नहीं हुईं, और सिर्फ high concurrency·long context environment में ही दिखाई दीं.
मुख्य परिणाम सारांश
| मद | मान |
|---|---|
| Bug Fix #1 लागू होने के बाद असामान्य output अनुपात | 0.1% → 0.03% से कम |
| LayerSplit throughput सुधार (40K~120K tokens) | +10% ~ +132% |
| HiCache fix को SGLang PR #22811 के रूप में योगदान | ✅ |
असामान्य व्यवहार की पहचान: Speculative Decoding metrics का उपयोग
असामान्य व्यवहार को अपने-आप detect करना ही एक कठिन समस्या थी. Regex जैसे heuristic तरीकों में false positive·false negative बहुत थे, और model-based classifier बड़े पैमाने के प्रयोगों के लिए बहुत महंगे थे.
ब्रेकथ्रू Speculative Decoding metric से मिला.
- garbled output / rare characters:
spec_accept_lengthअत्यंत कम → draft model और target model के KV Cache state mismatch का संकेत - repeated generation:
spec_accept_rateअत्यंत अधिक → corrupted KV Cache के कारण attention pattern के repetitive loop में converge होने का संकेत
इसके आधार पर online monitoring strategy लागू की गई. यदि generated token 128 से अधिक होने के बाद spec_accept_length < 1.4 या spec_accept_rate > 0.96 हो, तो generation तुरंत रोककर load balancer को retry सौंप दिया जाता है. यानी Speculative Decoding performance optimization tool से output quality के real-time monitoring tool तक विस्तारित हो गया.
Bug Fix #1: PD विभाजित architecture में KV Cache race condition
कारण
PD(Prefill-Decode) विभाजित architecture में tail latency नियंत्रण के लिए timeout-आधारित request interruption mechanism चलाया जा रहा था. यदि Prefill तय समय के भीतर पूरा नहीं होता, तो Decode पक्ष उस request को abort कर देता है और KV Cache को reclaim कर लेता है.
समस्या यह थी कि abort signal Prefill पक्ष तक सही तरह से नहीं पहुँच रहा था. Decode द्वारा KV Cache reclaim करके उसे नई request (Req2) को reassign करने के बाद भी, पुरानी request (Req1) का RDMA write और Prefill computation जारी रहता था, जिससे Req2 के KV Cache पर overwrite हो रहा था.
समाधान
Decode द्वारा abort जारी करने के बाद Prefill पक्ष को notification भेजा जाने लगा, और Prefill को केवल नीचे की दो शर्तों में से किसी एक के पूरा होने पर ही "reclaim safe" signal लौटाने के लिए बदला गया.
- RDMA write अभी शुरू ही नहीं हुआ हो
- पहले से जारी किए गए सभी write पूरे हो चुके हों
Decode अब यह पुष्टि मिलने के बाद ही KV Cache का पुन: उपयोग करता है. इसे लागू करने के बाद असामान्य output अनुपात 0.1% → 0.03% से कम हो गया.
Bug Fix #2: HiCache में Load-Use ordering guarantee की कमी
कारण
Coding Agent workload में औसत input length 70K tokens से अधिक है और prefix reuse rate भी ऊँचा है. इसके लिए HiCache (hierarchical KV Cache) चलाया जा रहा था, जिसमें CPU memory से KV Cache को asynchronously swap-in करते हुए Load Stream और Forward Stream को overlap करके चलाया जाता है.
समस्या यह थी कि Indexer kernel ने Indexer cache load completion के साथ synchronization constraint को स्पष्ट रूप से निर्दिष्ट नहीं किया था. यदि Forward Stream, Load Stream से पहले चलना शुरू कर दे, तो अभी लोड न हुए KV Cache को पढ़ने वाला read-before-ready pattern बनता था, जो असामान्य output का कारण बनता था.
समाधान
Indexer kernel के चलने से पहले Load Stream के साथ explicit synchronization point डाला गया, ताकि data तैयार होने के बाद ही Forward Stream computation आगे बढ़ाए. यह सुधार SGLang community में PR #22811 के रूप में योगदान किया गया.
Optimization: LayerSplit (layer-स्तर KV Cache distributed storage)
इन दोनों bug का साझा bottleneck Prefill चरण का लोड था. इसे मूल रूप से सुधारने के लिए LayerSplit को डिज़ाइन और implement किया गया.
पहले Context Parallelism(CP) environment में हर GPU सभी layers के KV Cache को duplicate रूप से store करता था. LayerSplit में हर GPU सिर्फ कुछ layers की ज़िम्मेदारी लेकर distributed storage करता है, जिससे प्रति GPU memory usage बहुत कम हो जाता है.
Execution के समय संबंधित layer का KV Cache रखने वाला CP rank attention computation से पहले cache को broadcast करता है. Broadcast और indexer computation को overlap करके communication overhead छिपाया गया, और अतिरिक्त communication data केवल indexer cache (KV Cache के लगभग 1/8 आकार) तक सीमित होने से कुल overhead लगभग नगण्य रहा.
90% cache hit rate की स्थिति में 40K~120K token requests पर throughput 10%~132% बेहतर हुआ, और context length जितनी लंबी होती है, सुधार उतना अधिक बढ़ता है.
निष्कर्ष
> "केवल throughput, latency और availability काफ़ी नहीं हैं. सिस्टम को हर generation request के पीछे model state की सहीपन भी सुनिश्चित करनी होगी. Scaling Laws क्षमता को आगे धकेलते हैं, लेकिन उस क्षमता को बड़े पैमाने पर भरोसेमंद बनाने का काम केवल कठोर system engineering ही कर सकती है."
स्रोत: Z.ai Research Blog (2026-04-30)
अभी कोई टिप्पणी नहीं है.