Testing the DDTree Standalone Server: A Diagnostic Pivot from Training to Deployment

Introduction

In the course of a complex ML engineering session spanning environment setup, training optimization, and model deployment, the assistant reached a critical inflection point: the pivot from training the DFlash speculative decoding system to deploying it on production hardware. Message [msg 10925] captures a precise diagnostic moment—a dual-mode test of a freshly deployed standalone DDTree (Draft-Driven Tree) server on a Pro6000 GPU machine. This message, though outwardly a simple bash command executing a Python script, reveals the assistant's systematic approach to validating an inference service before trusting it for production use. By comparing the server's behavior with and without "thinking mode" enabled, the assistant uncovers a significant quality gap that would otherwise remain hidden behind a passing health check.

The Message in Full

The message consists of a single SSH command that runs a Python script on the CT200 container (a Pro6000 GPU host). The script sends two HTTP requests to the DDTree OpenAI-compatible server running on 127.0.0.1:30000, varying only the enable_thinking parameter:

for enable in [False, True]:
    payload = {
        'model': 'qwen3.6-27b-zlab-ddtree',
        'messages': [{'role': 'user', 'content': 'Say hello in one short sentence.'}],
        'max_tokens': 48,
        'temperature': 0,
        'tree_budget': 64,
        'enable_thinking': enable,
    }
    # ... send request and print results

The results are starkly different. With enable_thinking=False, the server returns a clean "Hello," — short but coherent. The DDTree metrics show 1 decode round, mean acceptance length of 4.0 tokens, and a throughput of ~24 tokens/second. With enable_thinking=True, the output degenerates into garbled text: "Thinking to the 1. 1. 题目:\nuser:\n# user: 1.\n# 1. 1. 1. 年 1 1. 三角形\n1." — a corrupted thinking trace mixing Chinese characters and numbering. The decode rounds jump to 22, mean acceptance length drops to 2.23, and throughput plummets to ~4.6 tokens/second.

Why This Message Was Written: Reasoning and Motivation

The message was written as a deliberate diagnostic step in a multi-phase deployment process. To understand its motivation, we must trace the preceding actions. In earlier messages ([msg 10912] through [msg 10924]), the assistant had:

  1. Killed the active training run on CT200 to free resources for deployment
  2. Copied the z-lab DDTree code and draft model from the eval host (CT129) to CT200
  3. Set up a Python environment with necessary dependencies (fastapi, uvicorn, loguru)
  4. Written and deployed a standalone OpenAI-compatible server wrapper (ddtree_openai_server.py)
  5. Created a systemd service and verified it started successfully via a health endpoint
  6. Run an initial smoke test with tree_budget=16 ([msg 10924]) that returned a garbled response The initial smoke test in [msg 10924] used tree_budget=16 and produced output that mixed Chinese characters with English in a way that suggested the model was generating a thinking/reasoning trace rather than a direct response. The assistant's reasoning, visible in the sequence of actions, was to investigate this anomaly systematically. The hypothesis was that the "thinking mode" prompt format (used internally by Qwen3.6-27B for chain-of-thought reasoning) might be interfering with the DDTree generation process. By testing both enable_thinking=False and enable_thinking=True with a larger tree budget of 64, the assistant could isolate whether the garbled output was caused by thinking mode or by the draft model's quality at small tree budgets. The choice of tree_budget=64 (up from 16) reflects another hypothesis: that a larger tree budget would give the draft model more candidates to explore, potentially improving acceptance length and output quality. This is a standard speculative debugging technique—if the draft model is too conservative, increasing the tree budget may help, but if the issue is fundamental (e.g., prompt format mismatch), it won't matter.

Decisions and Assumptions

Several decisions shaped this test, each carrying implicit assumptions:

Decision 1: Test both thinking modes in a single script. The assistant could have run two separate commands, but combining them into one loop ensured identical conditions (same model load state, same server process) for a fair comparison. The assumption was that the server's state would be stable across requests.

Decision 2: Use temperature=0. This ensures deterministic output, making the test reproducible. The assumption was that the DDTree implementation respects temperature settings correctly—if it doesn't, the results would be misleading.

Decision 3: Set max_tokens=48. This is generous enough to see meaningful output patterns but short enough to avoid excessive wait time (the server was already showing ~4.6 tok/s in thinking mode). The assumption was that 48 tokens would reveal the output quality pattern.

Decision 4: Use the same simple prompt. "Say hello in one short sentence" is unambiguous and should produce a short English response. The assumption was that the model's basic instruction-following capability was intact.

Decision 5: Trust the DDTree metrics. The assistant printed ddtree fields like decode_rounds, mean_acceptance_length, and tokens_per_second. The assumption was that these metrics are accurately computed by the server and reflect genuine generation behavior.

Mistakes and Incorrect Assumptions

The most significant revelation is that the thinking mode output is clearly broken. The garbled text—"Thinking to the 1. 1. 题目:\nuser:\n# user: 1.\n# 1. 1. 1. 年 1 1. 三角形\n1."—appears to be a corrupted version of the model's internal thinking trace, where the model is trying to reason about the prompt in Chinese but the output is truncated, repeated, or mixed with formatting artifacts. This suggests one or more of the following issues:

  1. The thinking mode prompt format is incompatible with DDTree. The DDTree server may be passing the thinking instruction incorrectly, or the draft model may not handle the special <thinking> tags that Qwen3.6 uses for chain-of-thought.
  2. The draft model was not trained on thinking-mode data. The z-lab DFlash draft model may only be trained on direct responses, not on the model's internal reasoning traces. When thinking mode is enabled, the target model produces a different distribution (thinking tokens before the answer), and the draft model cannot predict this distribution well.
  3. The acceptance criterion is too strict for thinking tokens. The mean acceptance length drops from 4.0 (non-thinking) to 2.23 (thinking), suggesting that the draft model's predictions are accepted less frequently in thinking mode. This is consistent with a distribution mismatch.
  4. The output is truncated or the server has a bug. The JSON output in the message ends with "..." (ellipsis), suggesting the full response was cut off in the display. The actual server response may contain more data. Additionally, even the non-thinking mode output is suspicious. "Hello," with only 3 output tokens is an unusually short response to "Say hello in one short sentence." A well-tuned model would typically produce something like "Hello! How can I help you today?" or "Hello there!" The fact that only 3 tokens were generated (and the response ends with a comma, suggesting incompleteness) indicates that either the DDTree generation terminated early or the max_tokens limit was interpreted differently. The assumption that tree_budget=64 would improve quality over tree_budget=16 is not validated by these results. The non-thinking output at budget 64 is still very short (3 tokens), and the thinking output is garbled. The earlier test at budget 16 ([msg 10924]) produced 24 tokens of garbled output—so increasing the budget didn't fix the fundamental quality issue.

Input Knowledge Required

To fully understand this message, one needs knowledge of:

Output Knowledge Created

This message produces several valuable pieces of knowledge:

  1. The DDTree server is operational and responds correctly to the API. Both requests returned HTTP 200 with valid JSON, confirming the server infrastructure works.
  2. Non-thinking mode produces coherent but very short output. The model can generate reasonable text, but the generation terminates early—possibly due to the draft model's confidence threshold or a bug in the stop condition.
  3. Thinking mode is broken. The output is garbled and the performance degrades significantly (4.6 tok/s vs 24 tok/s). This is a critical finding that must be addressed before the server can be used with thinking mode enabled.
  4. Performance baselines are established. Non-thinking mode achieves ~24 tok/s with mean acceptance of 4 tokens per round. Thinking mode achieves only ~4.6 tok/s with mean acceptance of 2.23 tokens. These numbers serve as baselines for future optimization.
  5. The draft model's behavior differs between modes. The acceptance length drops by nearly half in thinking mode, confirming a distribution mismatch between what the draft model predicts and what the target model accepts.

The Thinking Process Visible in the Message

Although the ## Agent Reasoning section in this message contains no explicit text, the reasoning is embedded in the design of the test itself. The assistant is performing a controlled experiment:

Conclusion

Message [msg 10925] is a masterclass in systematic diagnostic testing during a complex deployment process. By designing a simple but powerful experiment—comparing thinking and non-thinking modes with a larger tree budget—the assistant quickly identified that the DDTree server has a fundamental issue with thinking mode generation while confirming that basic generation works. This knowledge directly informs the next steps: either fix the thinking mode prompt handling in the DDTree server, disable thinking mode for production use, or investigate the draft model's training data for thinking-mode coverage. The message exemplifies how a well-crafted test can produce maximum diagnostic value from minimal code, turning a simple bash command into a critical decision point in the deployment pipeline.