From 8f7a940023adf7670656c794a42f1c2be22396ea Mon Sep 17 00:00:00 2001 From: dhunganapramod9 Date: Sat, 28 Feb 2026 01:07:26 -0500 Subject: [PATCH 1/3] fix(chat_web): add argparse choices for --source to avoid KeyError on invalid value --- scripts/chat_web.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/chat_web.py b/scripts/chat_web.py index 66d7806..4d4eacf 100644 --- a/scripts/chat_web.py +++ b/scripts/chat_web.py @@ -62,7 +62,7 @@ MAX_MAX_TOKENS = 4096 parser = argparse.ArgumentParser(description='NanoChat Web Server') parser.add_argument('-n', '--num-gpus', type=int, default=1, help='Number of GPUs to use (default: 1)') -parser.add_argument('-i', '--source', type=str, default="sft", help="Source of the model: sft|rl") +parser.add_argument('-i', '--source', type=str, default="sft", choices=["sft", "rl"], help="Source of the model: sft|rl") parser.add_argument('-t', '--temperature', type=float, default=0.8, help='Default temperature for generation') parser.add_argument('-k', '--top-k', type=int, default=50, help='Default top-k sampling parameter') parser.add_argument('-m', '--max-tokens', type=int, default=512, help='Default max tokens for generation') From 20c385e8f7a53475b7894e4168e044121a8cb419 Mon Sep 17 00:00:00 2001 From: dhunganapramod9 Date: Sat, 28 Feb 2026 01:07:55 -0500 Subject: [PATCH 2/3] fix(chat_web): use removeprefix for SSE chunk to avoid corrupting payload when token contains 'data: ' --- scripts/chat_web.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/chat_web.py b/scripts/chat_web.py index 4d4eacf..c0f9477 100644 --- a/scripts/chat_web.py +++ b/scripts/chat_web.py @@ -360,7 +360,7 @@ async def chat_completions(request: ChatRequest): top_k=request.top_k ): # Accumulate response for logging - chunk_data = json.loads(chunk.replace("data: ", "").strip()) + chunk_data = json.loads(chunk.removeprefix("data: ").strip()) if "token" in chunk_data: response_tokens.append(chunk_data["token"]) yield chunk From 37d23102b6c177097049bb17bd74827569b6dd33 Mon Sep 17 00:00:00 2001 From: dhunganapramod9 Date: Sun, 1 Mar 2026 09:02:57 -0500 Subject: [PATCH 3/3] fix(chat_cli,chat_eval): add --source choices and validate --task-name to avoid KeyError --- scripts/chat_cli.py | 2 +- scripts/chat_eval.py | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/chat_cli.py b/scripts/chat_cli.py index 7de7e10..d1c07f3 100644 --- a/scripts/chat_cli.py +++ b/scripts/chat_cli.py @@ -12,7 +12,7 @@ from nanochat.engine import Engine from nanochat.checkpoint_manager import load_model parser = argparse.ArgumentParser(description='Chat with the model') -parser.add_argument('-i', '--source', type=str, default="sft", help="Source of the model: sft|rl") +parser.add_argument('-i', '--source', type=str, default="sft", choices=["sft", "rl"], help="Source of the model: sft|rl") parser.add_argument('-g', '--model-tag', type=str, default=None, help='Model tag to load') parser.add_argument('-s', '--step', type=int, default=None, help='Step to load') parser.add_argument('-p', '--prompt', type=str, default='', help='Prompt the model, get a single response back') diff --git a/scripts/chat_eval.py b/scripts/chat_eval.py index bc15239..959b85e 100644 --- a/scripts/chat_eval.py +++ b/scripts/chat_eval.py @@ -183,7 +183,7 @@ if __name__ == "__main__": # Parse command-line arguments parser = argparse.ArgumentParser() - parser.add_argument('-i', '--source', type=str, required=True, help="Source of the model: sft|rl") + parser.add_argument('-i', '--source', type=str, required=True, choices=["sft", "rl"], help="Source of the model: sft|rl") parser.add_argument('-a', '--task-name', type=str, default=None, help="Task name. Default = all tasks. Use | to split multiple tasks.") parser.add_argument('-d', '--dtype', type=str, default='bfloat16', choices=['float32', 'bfloat16']) parser.add_argument('-t', '--temperature', type=float, default=0.0) @@ -215,7 +215,10 @@ if __name__ == "__main__": 'HumanEval': 0.0, # open-ended => 0% 'SpellingBee': 0.0, # open-ended => 0% } - task_names = all_tasks if args.task_name is None else args.task_name.split('|') + task_names = all_tasks if args.task_name is None else [t.strip() for t in args.task_name.split('|')] + for task_name in task_names: + if task_name not in all_tasks: + raise ValueError(f"Invalid task name: {task_name!r}. Choose from: {', '.join(all_tasks)}") # Run all the task evaluations sequentially results = {}