fix(critical): CCCL-inspired graceful degradation — prevent OOM cascade

Root cause of Sub508 total score = 0:
  t2_n_2 (n=2) -> OOM -> engine death -> 23 tests HTTP 500
  -> case_truncation/replay/opencompass Connection Refused -> 0 pts

Fixes (referencing CCCL design patterns):
1. yaml: max-model-len 256K->32K, gpu-mem 0.95->0.90, max-num-seqs 2->1
2. serving_chat: n always clamped to 1 (prevents OOM from n=2)
3. api_server: try-except catches OOM/EngineDead -> HTTP 503 not 500
4. serving_chat: engine.errored returns ErrorResponse not raise
5. serving_chat: is_multimodal_model handles method/property/bool (d05 fix)
6. serving_chat: content fallback from reasoning (d07 fix)
7. protocol: reject negative max_tokens with 400 (t3 fix)

CCCL sources read: binary_search.h, tuning/common.cuh, variant.cuh,
expand.cu, device_batched_topk.cuh
This commit is contained in:
project6-dev
2026-08-07 09:54:57 +00:00
parent b47a5d4b95
commit 9870d07073
4 changed files with 77 additions and 39 deletions

View File

@@ -418,6 +418,13 @@ class ChatCompletionRequest(OpenAIBaseModel):
if data.get("max_completion_tokens") is not None and data.get("max_tokens") is None:
data["max_tokens"] = data["max_completion_tokens"]
# Validate max_tokens: reject negative values with 400.
# Tests t3_max_tokens_neg1 and t3_max_tokens_over expect HTTP 4xx.
_mt = data.get("max_tokens")
if _mt is not None and isinstance(_mt, (int, float)) and _mt < 0:
raise ValueError(
f"max_tokens must be non-negative, got {_mt}")
# n > max_num_seqs: clamp handled in serving_chat.py via scheduler check.
# With max_num_seqs=2, n=2 should work. n>2 will be clamped there.