Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion fastdeploy/engine/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

from __future__ import annotations

import dataclasses
import json
import time
import traceback
Expand Down Expand Up @@ -896,7 +897,27 @@ def to_dict(self):
"""
Convert the RequestMetrics object to a dictionary.
"""
return {k: v for k, v in asdict(self).items()}
d = {}
for k in self.__dataclass_fields__:
v = getattr(self, k)
if v is None or type(v) in (int, float, str, bool):
d[k] = v
Comment on lines +900 to +904
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

PR 标题目前为 "⚡ Bolt: Optimize RequestMetrics serialization performance",不符合仓库约定的 [CLASS]Title 格式(例如 [BugFix] ... / [Perf] ...)。建议将标题调整为类似 [Perf] Optimize RequestMetrics serialization performance,便于后续自动化发布/检索。

Copilot generated this review using guidance from repository custom instructions.
elif dataclasses.is_dataclass(v):
if hasattr(v, "to_dict"):
d[k] = v.to_dict()
else:
d[k] = asdict(v)
elif isinstance(v, list):
Comment on lines +900 to +910
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

这里优化了 RequestMetrics.to_dict(),但当前代码库里仍存在直接 asdict(self.metrics) 的调用(例如 Request.to_dict()),会绕过本次优化并继续触发 dataclasses.asdict 的深拷贝开销。建议把这些调用点改为 self.metrics.to_dict()(并在 metrics 可能为 None 时做一致处理),确保性能收益真正落到请求序列化主路径上。

Copilot uses AI. Check for mistakes.
# Note: This is a shallow copy for performance. If RequestMetrics
# ever contains lists of nested dataclasses, they must be manually
# serialized here or fallback to asdict.
d[k] = list(v)
elif isinstance(v, dict):
# Note: This is a shallow copy for performance.
d[k] = dict(v)
else:
d[k] = v
return d

def record_recv_first_token(self):
cur_time = time.time()
Expand Down
10 changes: 10 additions & 0 deletions fastdeploy/worker/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,16 @@ class SpeculateMetrics:
"""
accept_ratio_per_head: list[float]

def to_dict(self):
return {
"accepted_tokens": self.accepted_tokens,
"rejected_tokens": self.rejected_tokens,
"accept_ratio": self.accept_ratio,
"average_accept_length": self.average_accept_length,
"accepted_tokens_per_head": self.accepted_tokens_per_head,
"accept_ratio_per_head": self.accept_ratio_per_head,
}


@dataclass
class SamplerOutput:
Expand Down
Loading