Skip to content

Add DeepSeek persistent L3 profiling - #111

Merged
superxf merged 1 commit into
hw-native-sys:mainfrom
high-cloud:skill
Jul 24, 2026
Merged

Add DeepSeek persistent L3 profiling#111
superxf merged 1 commit into
hw-native-sys:mainfrom
high-cloud:skill

Conversation

@high-cloud

Copy link
Copy Markdown
Contributor

What changed

  • Run DeepSeek V4 L3 programs through a persistent DistributedWorker so communication domains and worker state are reused across requests.
  • Add DeepSeek compile, worker setup, buffer/weight preparation, prefill/decode, MTP, LM-head, and L3 dispatch profiling spans, including host/device runtime timing.
  • Make the DeepSeek accuracy harness shut down uvicorn gracefully before escalating to process-group termination, allowing the serving worker and profiling fragments to clean up normally.

Why

DeepSeek serving previously had persistent-L3 support at the model runner boundary but lacked complete framework-level timing coverage. The accuracy harness also terminated the whole process group immediately, which could leave the serving worker or profiling merge incomplete.

Validation

  • python -m pytest tests/test_deepseek_v4.py -q — 31 passed
  • python -m pytest tests/test_deepseek_v4_accuracy.py -q -k 'not deepseek_v4_http_completion_matches_expected_text' — 3 passed
  • Ruff and git diff --check passed
  • Real 8-card DeepSeek accuracy run on devices 8–15 — 4 passed

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e847f492-cd58-4247-9b58-1c0544e30133

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

DeepSeek V4 compilation and serving paths now emit profiling spans with execution timings and metadata across prefill, decode, MTP, L3, buffer, weight, and worker operations. Accuracy-test process shutdown now uses staged signal escalation.

Changes

DeepSeek V4 profiling

Layer / File(s) Summary
Profiling helpers and callable metadata
pypto_serving/model/deepseek/npu_executor.py, pypto_serving/model/deepseek/npu_runner.py
Compilation is wrapped in executor profiling, stable kernel trace names and timing arguments are added, and DeepSeekV4L3Callable gains block_dim and aicpu_thread_num.
Prefill and decode stage tracing
pypto_serving/model/deepseek/npu_runner.py
Prefill, decode, autoregressive, and MTP preparation, dispatch, draft advancement, and logits stages are wrapped in profiling spans with scalar arguments.
L3 execution and resource tracing
pypto_serving/model/deepseek/npu_runner.py, tests/test_deepseek_v4.py
L3 worker and kernel spans now include timing and execution metadata; shared resources, resident weights, and persistent worker creation are profiled, with persistent-worker construction validated.

Accuracy-test process shutdown

Layer / File(s) Summary
Staged process termination
tests/test_deepseek_v4_accuracy.py
Process shutdown now escalates from parent-PID SIGINT to SIGTERM and then process-group SIGKILL, with longer waits and mocked parent signaling in the timeout test.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant DeepSeekV4ModelRunner
  participant profile_span
  participant _run_l3
  participant DistributedWorker
  DeepSeekV4ModelRunner->>profile_span: trace serving preparation and logits
  DeepSeekV4ModelRunner->>_run_l3: dispatch L3 callable
  _run_l3->>profile_span: create outer and worker spans
  _run_l3->>DistributedWorker: execute worker callable
  DistributedWorker-->>_run_l3: provide execution timing
Loading

Possibly related PRs

Poem

A rabbit watches kernels glow,
Through prefill hops and logits flow.
L3 workers trace each tiny beat,
While sleepy processes face defeat.
SIGINT, SIGTERM—then lights go dim,
Clean shutdowns make the burrow grin.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and clearly reflects the main DeepSeek L3 profiling change.
Description check ✅ Passed The description matches the changeset, covering persistent workers, profiling spans, and graceful shutdown updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@high-cloud
high-cloud marked this pull request as ready for review July 23, 2026 09:26

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pypto_serving/model/deepseek/npu_runner.py`:
- Around line 2101-2111: Update the profile_span metadata in the decode MTP
advance block to represent acceptance across the entire batch, replacing the
request-specific len(accepted[0]) value with the per-request accepted-count
tuple or an explicitly documented aggregate. Keep the existing
_advance_mtp_drafts call and acceptance behavior unchanged.
- Around line 945-946: Update the DeepSeekV4L3Callable construction in _run_l3
to populate block_dim and aicpu_thread_num from the applicable compile/runtime
configuration instead of relying on dataclass defaults; if either value is
unavailable, omit it or preserve an explicitly unknown value rather than
recording block_dim=None and aicpu_thread_num=4.

In `@tests/test_deepseek_v4_accuracy.py`:
- Line 216: In the process-wait exception handlers around the affected test
cleanup logic, replace the broad Exception catches with only the expected
OSError and supported subprocess exception types. Update all three handlers at
the referenced locations while preserving their existing suppression behavior
and conforming to the repository’s Ruff configuration.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b6d3b192-6116-42ab-90bb-15295d2503cb

📥 Commits

Reviewing files that changed from the base of the PR and between 2fed003 and af2e69c.

📒 Files selected for processing (4)
  • pypto_serving/model/deepseek/npu_executor.py
  • pypto_serving/model/deepseek/npu_runner.py
  • tests/test_deepseek_v4.py
  • tests/test_deepseek_v4_accuracy.py

Comment on lines +945 to +946
block_dim: int | None = None
aicpu_thread_num: int = 4

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Locate files:"
fd -a 'npu_(runner|executor)\.py$' . || true

echo
echo "Check relevant symbols/usages:"
rg -n "class DeepSeekV4L3Callable|def _compile_l3_callable|compile_l3|DeepSeekV4L3Callable\(" -S .

echo
echo "Inspect relevant lines:"
for f in $(fd 'npu_(runner|executor)\.py$' .); do
  echo "===== $f ====="
  wc -l "$f"
done

Repository: hw-native-sys/pypto-serving

Length of output: 2379


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "===== runner callable metadata/default lines ====="
sed -n '920,970p' pypto_s serving/model/deepseek/npu_runner.py 2>/dev/null || sed -n '920,970p' pypto_serving/model/deepseek/npu_runner.py

echo
echo "===== _compile_l3_callable implementation ====="
sed -n '480,550p' pypto_serving/model/deepseek/npu_executor.py

echo
echo "===== compilation args and callables around l3 compile calls ====="
sed -n '360,435p' pypto_serving/model/deepseek/npu_executor.py

echo
echo "===== search for aicpu_thread_num/block_dim in runner/executor ====="
rg -n "aicpu_thread_num|block_dim" pypto_serving/model/deepseek/npu_runner.py pypto_serving/model/deepseek/npu_executor.py -C 2

Repository: hw-native-sys/pypto-serving

Length of output: 9535


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "===== call sites for DeepSeekV4L3Callable/span metadata ====="
rg -n "DeepSeekV4L3Callable|profile_span\(.*kernel|block_dim|aicpu_thread_num" pypto_serving/model pypto_serving -S --glob '*.py' -C 2

echo
echo "===== read-only verifier: construction call sites and defaults ====="
python3 - <<'PY'
from pathlib import Path
import re

runner = Path("pypto_serving/model/deepseek/npu_runner.py").read_text()
executor = Path("pypto_serving/model/deepseek/npu_executor.py").read_text()

constructor = re.search(r"return DeepSeekV4L3Callable\((?P<body>.*?)(?:\n[A-Za-z_][A-Za-z0-9_]*|$\s*$)", executor, re.S)
print("constructor_text:", re.sub(r"\s+", " ", constructor.group(0)))
print("passes_block_dim:", "block_dim" in executor)
print("passes_aicpu_thread_num:", "aicpu_thread_num" in executor)

print("callable class fields:")
class_match = re.search(r"`@dataclass`\n\nclass DeepSeekV4L3Callable:\n(?P<body>.*?\n\nclass )", runner, re.S | re.M)
for line in class_match.group(0).splitlines():
    if re.match(r'\s+(compiled|name|block_dim|aicpu_thread_num)\s*:', line):
        print(line.strip())

print("span args include callable metadata:", "span_args = {" in runner and '"block_dim": callable_spec.block_dim' in runner)
PY

Repository: hw-native-sys/pypto-serving

Length of output: 37820


Populate L3 callable metadata in production compilation.

DeepSeekV4L3Callable(compiled=compiled, name=name) relies on the dataclass defaults, so kernels traced by _run_l3 always record block_dim=None and aicpu_thread_num=4. Populate these fields from the compile/runtime configuration, or omit them until their values are known.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pypto_serving/model/deepseek/npu_runner.py` around lines 945 - 946, Update
the DeepSeekV4L3Callable construction in _run_l3 to populate block_dim and
aicpu_thread_num from the applicable compile/runtime configuration instead of
relying on dataclass defaults; if either value is unavailable, omit it or
preserve an explicitly unknown value rather than recording block_dim=None and
aicpu_thread_num=4.

Comment on lines +2101 to +2111
with profile_span(
"DeepSeekV4ModelRunner.decode.mtp_advance",
cat="executor",
args={"accepted_count": len(accepted[0]) if accepted else 0},
):
self._advance_mtp_drafts(
inputs,
main_ids,
output.pre_hc_hidden,
accepted_counts=tuple(len(tokens) for tokens in accepted),
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Record MTP acceptance for the whole batch.

accepted is request-specific, but the span records only len(accepted[0]); mixed batches therefore expose misleading metadata. Record the per-request tuple or an explicitly documented aggregate.

Suggested adjustment
-            args={"accepted_count": len(accepted[0]) if accepted else 0},
+            args={"accepted_counts": tuple(len(tokens) for tokens in accepted)},
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
with profile_span(
"DeepSeekV4ModelRunner.decode.mtp_advance",
cat="executor",
args={"accepted_count": len(accepted[0]) if accepted else 0},
):
self._advance_mtp_drafts(
inputs,
main_ids,
output.pre_hc_hidden,
accepted_counts=tuple(len(tokens) for tokens in accepted),
)
with profile_span(
"DeepSeekV4ModelRunner.decode.mtp_advance",
cat="executor",
args={"accepted_counts": tuple(len(tokens) for tokens in accepted)},
):
self._advance_mtp_drafts(
inputs,
main_ids,
output.pre_hc_hidden,
accepted_counts=tuple(len(tokens) for tokens in accepted),
)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pypto_serving/model/deepseek/npu_runner.py` around lines 2101 - 2111, Update
the profile_span metadata in the decode MTP advance block to represent
acceptance across the entire batch, replacing the request-specific
len(accepted[0]) value with the per-request accepted-count tuple or an
explicitly documented aggregate. Keep the existing _advance_mtp_drafts call and
acceptance behavior unchanged.

Comment thread tests/test_deepseek_v4_accuracy.py Outdated
process.wait(timeout=10)
except subprocess.TimeoutExpired:
print(f"WARNING: process group {process.pid} still alive after SIGKILL", flush=True)
except Exception as exc:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Replace blind Exception handlers with expected process-wait errors.

Lines 216, 218, and 221 suppress unrelated failures and trigger Ruff BLE001. Catch OSError and explicitly supported subprocess exceptions instead.

Proposed fix
-            except Exception as exc:
+            except OSError as exc:
                 print(f"WARNING: failed to reap process group {process.pid}: {exc}", flush=True)
...
-        except Exception as exc:
+        except OSError as exc:
             print(f"WARNING: failed to reap process group {process.pid}: {exc}", flush=True)
...
-    except Exception as exc:
+    except OSError as exc:
         print(f"WARNING: failed to wait for process group {process.pid}: {exc}", flush=True)

As per coding guidelines, follow the repository’s Ruff configuration.

Also applies to: 218-218, 221-221

🧰 Tools
🪛 Ruff (0.15.21)

[warning] 216-216: Do not catch blind exception: Exception

(BLE001)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_deepseek_v4_accuracy.py` at line 216, In the process-wait
exception handlers around the affected test cleanup logic, replace the broad
Exception catches with only the expected OSError and supported subprocess
exception types. Update all three handlers at the referenced locations while
preserving their existing suppression behavior and conforming to the
repository’s Ruff configuration.

Sources: Coding guidelines, Linters/SAST tools

@superxf
superxf merged commit 909ca26 into hw-native-sys:main Jul 24, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants