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
20 changes: 18 additions & 2 deletions fastdeploy/engine/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import json
import time
import traceback
from dataclasses import asdict, dataclass, fields
from dataclasses import asdict, dataclass, fields, is_dataclass
from enum import Enum
from typing import Any, Dict, Generic, Optional
from typing import TypeVar as TypingTypeVar
Expand Down Expand Up @@ -896,7 +896,23 @@ def to_dict(self):
"""
Convert the RequestMetrics object to a dictionary.
"""
return {k: v for k, v in asdict(self).items()}
d = {}
for f in self.__dataclass_fields__:
v = getattr(self, f)
if type(v) in (int, float, str, bool, type(None)):
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

PR 标题目前不符合仓库约定的「[CLASS]Title」格式(例如 [Perf] Optimize RequestMetrics to_dict serialization ...)。建议去掉 emoji/前缀并按该格式重命名,以便后续自动化工具/发布记录识别。

Suggested change
if type(v) in (int, float, str, bool, type(None)):
if isinstance(v, (int, float, str, bool, type(None))):

Copilot uses AI. Check for mistakes.
d[f] = v
elif is_dataclass(v):
if hasattr(v, "to_dict"):
d[f] = v.to_dict()
else:
d[f] = asdict(v)
elif isinstance(v, list):
d[f] = list(v)
elif isinstance(v, dict):
d[f] = dict(v)
else:
d[f] = v
return d

def record_recv_first_token(self):
cur_time = time.time()
Expand Down
24 changes: 23 additions & 1 deletion fastdeploy/worker/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# limitations under the License.
"""

from dataclasses import dataclass, field
from dataclasses import asdict, dataclass, field, is_dataclass
from typing import NamedTuple, Optional

import paddle
Expand Down Expand Up @@ -164,6 +164,28 @@ class SpeculateMetrics:
"""
accept_ratio_per_head: list[float]

def to_dict(self):
"""
Convert the SpeculateMetrics object to a dictionary.
"""
d = {}
for f in self.__dataclass_fields__:
v = getattr(self, f)
if type(v) in (int, float, str, bool, type(None)):
d[f] = v
elif is_dataclass(v):
if hasattr(v, "to_dict"):
d[f] = v.to_dict()
else:
d[f] = asdict(v)
elif isinstance(v, list):
d[f] = list(v)
elif isinstance(v, dict):
Comment on lines +171 to +183
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

SpeculateMetrics.to_dict 与 fastdeploy/engine/request.py 中 RequestMetrics.to_dict 的实现几乎完全重复。为降低后续维护成本(例如新增支持的容器类型/嵌套规则时避免两处漏改),建议抽成一个共享的轻量 dataclass 序列化工具函数并在两处复用。

Copilot uses AI. Check for mistakes.
d[f] = dict(v)
else:
d[f] = v
return d
Comment on lines +167 to +187
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

SpeculateMetrics 新增 to_dict 后建议增加对应单测(例如在 tests/output 或 tests/engine 中):确认返回的字段完整且都是可序列化的基础类型/list/dict,避免未来字段类型变化导致 RequestMetrics/接口输出不可序列化而难以及时发现。

Copilot generated this review using guidance from repository custom instructions.


@dataclass
class SamplerOutput:
Expand Down
Loading