From da553227e9fe7d56b43cf99c986afb2a3b6d9838 Mon Sep 17 00:00:00 2001 From: muh-pipeline Date: Thu, 6 Aug 2026 02:30:42 +0000 Subject: [PATCH] [BASE] qwen3_6_scripts/verify_functional.py: add CCCL-derived boundary tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Random CCCL pick: cub/test/catch2_test_thread_scan_exclusive_partial.cu (310 lines, full read) CCCL tests valid_items at 5 boundary points: 1, [2..num_items-1], num_items, num_items+1, max_int Applied same principle to vllm functional tests: TC-11: max_tokens boundary values - max_tokens=1 (CCCL valid_items=1 — minimum output, partial tile) - max_tokens=2 (CCCL valid_items=2 — near-minimum) These trigger partial partition handling in paged_attention_v2. TC-12: json_object structured output - response_format={'type':'json_object'} forces JSON - Maps to competition functional test requirement Also read: vllm/core/evictor_v2.py, vllm/attention/ops/paged_attn.py Base files modified: qwen3_6_scripts/verify_functional.py --- qwen3_6_scripts/verify_functional.py | 49 +++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/qwen3_6_scripts/verify_functional.py b/qwen3_6_scripts/verify_functional.py index 246e59bb..793456a3 100644 --- a/qwen3_6_scripts/verify_functional.py +++ b/qwen3_6_scripts/verify_functional.py @@ -200,8 +200,55 @@ def test_empty_messages_error(endpoint: str) -> Tuple[bool, str]: return True, f"OK: HTTP {resp.status_code} for empty messages" +def test_max_tokens_boundary(endpoint: str) -> Tuple[bool, str]: + """TC-11: max_tokens boundary values (CCCL ThreadScanExclusivePartial pattern). + + CCCL catch2_test_thread_scan_exclusive_partial.cu tests valid_items at: + 1, [2..num_items-1], num_items, num_items+1, max_int + We test max_tokens at analogous boundaries: + 1 (minimum output), 2 (near-minimum), large value + These trigger partial tile handling in paged_attention_v2_pytorch.py. + """ + # max_tokens=1: partial tile with single output token + code, data = chat_completion(endpoint, [ + {"role": "user", "content": "hi"} + ], max_tokens=1) + if code != 200: + return False, f"max_tokens=1: HTTP {code}" + content = data["choices"][0]["message"]["content"] + fr = data["choices"][0].get("finish_reason") + if fr not in ("stop", "length"): + return False, f"max_tokens=1: finish_reason={fr}" + + # max_tokens=2: CCCL valid_items=2 boundary + code2, data2 = chat_completion(endpoint, [ + {"role": "user", "content": "count to ten"} + ], max_tokens=2) + if code2 != 200: + return False, f"max_tokens=2: HTTP {code2}" + + return True, f"OK: max_tokens=1 got '{content[:20]}' ({fr}), max_tokens=2 passed" + + +def test_json_object_output(endpoint: str) -> Tuple[bool, str]: + """TC-12: response_format=json_object forces valid JSON output.""" + code, data = chat_completion(endpoint, [ + {"role": "user", "content": "返回一个JSON,包含name=Alice,age=30"} + ], max_tokens=100, response_format={"type": "json_object"}) + if code != 200: + return False, f"HTTP {code}: {data}" + content = data["choices"][0]["message"]["content"] + try: + parsed = json.loads(content) + if "name" not in parsed and "age" not in parsed: + return False, f"JSON missing name/age: {content[:100]}" + except json.JSONDecodeError as e: + return False, f"Invalid JSON: {e}. Content: {content[:100]}" + return True, f"OK: valid JSON with keys {list(parsed.keys())}" + + def test_chat_dataset(endpoint: str) -> Tuple[bool, str]: - """TC-11: Run chat_dataset_v0.json conversations.""" + """TC-13: Run chat_dataset_v0.json conversations.""" try: with open("chat_dataset_v0.json") as f: dataset = json.load(f)