feat: implement DGR-006 tensor bundle boundary
This commit is contained in:
@@ -31,6 +31,8 @@ from .codec import (
|
||||
checksum_of,
|
||||
crc32c,
|
||||
decode_bundle,
|
||||
decode_step_bundle,
|
||||
encode_decode_step,
|
||||
decode_tensor,
|
||||
default_flow_control,
|
||||
encode_bundle,
|
||||
@@ -40,6 +42,7 @@ from .codec import (
|
||||
negotiate_flow_control,
|
||||
plan_prefill_chunks,
|
||||
validate_session_message_size,
|
||||
validate_tail_result,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
@@ -60,6 +63,8 @@ __all__ = [
|
||||
"checksum_of",
|
||||
"crc32c",
|
||||
"decode_bundle",
|
||||
"decode_step_bundle",
|
||||
"encode_decode_step",
|
||||
"decode_tensor",
|
||||
"default_flow_control",
|
||||
"encode_bundle",
|
||||
@@ -70,4 +75,5 @@ __all__ = [
|
||||
"pb",
|
||||
"plan_prefill_chunks",
|
||||
"validate_session_message_size",
|
||||
"validate_tail_result",
|
||||
]
|
||||
|
||||
@@ -328,6 +328,8 @@ def decode_tensor(
|
||||
def encode_bundle(
|
||||
tensors: Iterable[pb.NamedTensor],
|
||||
*,
|
||||
architecture: int = pb.ARCHITECTURE_TYPE_UNSPECIFIED,
|
||||
boundary_point: str = "",
|
||||
max_chunk_bytes: int = DEFAULT_MAX_CHUNK_BYTES,
|
||||
max_tensors: int = DEFAULT_MAX_TENSORS_PER_BUNDLE,
|
||||
) -> pb.TensorBundle:
|
||||
@@ -338,7 +340,12 @@ def encode_bundle(
|
||||
raise ProtocolError(
|
||||
f"bundle carries {len(tensor_list)} tensors, exceeding limit {max_tensors}"
|
||||
)
|
||||
bundle = pb.TensorBundle(bundle_version=BUNDLE_VERSION, tensors=tensor_list)
|
||||
bundle = pb.TensorBundle(
|
||||
bundle_version=BUNDLE_VERSION,
|
||||
tensors=tensor_list,
|
||||
architecture=architecture,
|
||||
boundary_point=boundary_point,
|
||||
)
|
||||
if bundle.ByteSize() > max_chunk_bytes:
|
||||
raise ProtocolError(
|
||||
f"serialized tensor bundle exceeds the {max_chunk_bytes}-byte "
|
||||
@@ -392,6 +399,80 @@ def decode_bundle(
|
||||
return payloads
|
||||
|
||||
|
||||
def encode_decode_step(
|
||||
bundle: pb.TensorBundle,
|
||||
*,
|
||||
idempotency_step: int,
|
||||
position: int,
|
||||
expected_past_len: int,
|
||||
work_id: str,
|
||||
deadline_unix_nanos: int = 0,
|
||||
prefer_compact_one_tensor: bool = True,
|
||||
) -> pb.DecodeStep:
|
||||
"""Encode a decode boundary, retaining the deliberate compact fallback."""
|
||||
step = pb.DecodeStep(
|
||||
idempotency_step=idempotency_step,
|
||||
position=position,
|
||||
expected_past_len=expected_past_len,
|
||||
work_id=work_id,
|
||||
deadline_unix_nanos=deadline_unix_nanos,
|
||||
)
|
||||
if prefer_compact_one_tensor and len(bundle.tensors) == 1:
|
||||
step.tensor.CopyFrom(bundle.tensors[0])
|
||||
else:
|
||||
step.bundle.CopyFrom(bundle)
|
||||
return step
|
||||
|
||||
|
||||
def validate_tail_result(result: pb.TailResult) -> None:
|
||||
"""Fail closed unless a tail completion is bound to its exact recipe."""
|
||||
identity = result.identity
|
||||
required = (
|
||||
identity.request_id,
|
||||
identity.runtime_recipe_digest,
|
||||
identity.chat_template_id,
|
||||
identity.chat_template_version,
|
||||
identity.reasoning_mode,
|
||||
)
|
||||
if not all(required) or identity.architecture == pb.ARCHITECTURE_TYPE_UNSPECIFIED:
|
||||
raise ProtocolError("tail result lacks exact request/recipe/template identity")
|
||||
if result.WhichOneof("output") not in {"logits", "sampled_token_id"}:
|
||||
raise ProtocolError("tail result lacks logits or sampled token output")
|
||||
|
||||
|
||||
def decode_step_bundle(
|
||||
step: pb.DecodeStep,
|
||||
*,
|
||||
max_chunk_bytes: int = DEFAULT_MAX_CHUNK_BYTES,
|
||||
max_fragment_bytes: int = DEFAULT_MAX_FRAGMENT_BYTES,
|
||||
max_fragments: int = DEFAULT_MAX_FRAGMENTS_PER_TENSOR,
|
||||
max_tensors: int = DEFAULT_MAX_TENSORS_PER_BUNDLE,
|
||||
) -> dict[str, bytes]:
|
||||
"""Decode a fast-path boundary with the DGR-006 compatibility rule.
|
||||
|
||||
`bundle` is authoritative because it can carry architecture sidebands. The
|
||||
old `tensor` field remains the compact representation for a certified
|
||||
one-tensor boundary and is accepted by new readers during rollout.
|
||||
"""
|
||||
if step.HasField("bundle"):
|
||||
return decode_bundle(
|
||||
step.bundle,
|
||||
max_chunk_bytes=max_chunk_bytes,
|
||||
max_fragment_bytes=max_fragment_bytes,
|
||||
max_fragments=max_fragments,
|
||||
max_tensors=max_tensors,
|
||||
)
|
||||
if step.HasField("tensor"):
|
||||
return decode_bundle(
|
||||
encode_bundle([step.tensor], max_chunk_bytes=max_chunk_bytes),
|
||||
max_chunk_bytes=max_chunk_bytes,
|
||||
max_fragment_bytes=max_fragment_bytes,
|
||||
max_fragments=max_fragments,
|
||||
max_tensors=max_tensors,
|
||||
)
|
||||
raise ProtocolError("decode step carries neither TensorBundle nor legacy tensor")
|
||||
|
||||
|
||||
def validate_session_message_size(
|
||||
message: pb.SessionRequest | pb.SessionResponse,
|
||||
*,
|
||||
|
||||
@@ -27,6 +27,7 @@ TESTDATA_DIR = pathlib.Path(__file__).resolve().parents[2] / "native/testdata"
|
||||
|
||||
GOLDEN_SESSION_REQUEST = "session_request_golden.binpb"
|
||||
GOLDEN_CAPABILITY_REPORT = "capability_report_golden.binpb"
|
||||
GOLDEN_DECODE_STEP = "decode_step_golden.binpb"
|
||||
|
||||
# Written by the C++ conformance test into its build tree; the Python test picks
|
||||
# it up when present to prove the two languages agree byte-for-byte.
|
||||
@@ -136,6 +137,30 @@ def canonical_capability_report() -> pb.CapabilityReport:
|
||||
)
|
||||
|
||||
|
||||
def canonical_decode_step() -> pb.SessionRequest:
|
||||
"""The DGR-006 multi-tensor decode boundary vector."""
|
||||
hidden = codec.encode_tensor(
|
||||
codec.HIDDEN_STATES, bytes(range(16)), [1, 1, 4], pb.DTYPE_FLOAT32
|
||||
)
|
||||
index_topk = codec.encode_tensor(
|
||||
"index_topk", (3).to_bytes(4, "little"), [1], pb.DTYPE_INT32
|
||||
)
|
||||
return pb.SessionRequest(
|
||||
decode=pb.DecodeStep(
|
||||
idempotency_step=43,
|
||||
position=384,
|
||||
expected_past_len=384,
|
||||
work_id="decode-7f3a",
|
||||
deadline_unix_nanos=DEADLINE_UNIX_NANOS,
|
||||
bundle=codec.encode_bundle(
|
||||
[hidden, index_topk],
|
||||
architecture=pb.ARCHITECTURE_TYPE_MLA,
|
||||
boundary_point="pre_tail_residual",
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def serialize(message) -> bytes:
|
||||
"""Serialize deterministically, so committed golden bytes are stable."""
|
||||
return message.SerializeToString(deterministic=True)
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -12,6 +12,13 @@ class SchemaVersion(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
SCHEMA_VERSION_UNSPECIFIED: _ClassVar[SchemaVersion]
|
||||
SCHEMA_VERSION_1: _ClassVar[SchemaVersion]
|
||||
|
||||
class ArchitectureType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = ()
|
||||
ARCHITECTURE_TYPE_UNSPECIFIED: _ClassVar[ArchitectureType]
|
||||
ARCHITECTURE_TYPE_DENSE: _ClassVar[ArchitectureType]
|
||||
ARCHITECTURE_TYPE_MOE: _ClassVar[ArchitectureType]
|
||||
ARCHITECTURE_TYPE_MLA: _ClassVar[ArchitectureType]
|
||||
|
||||
class DType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = ()
|
||||
DTYPE_UNSPECIFIED: _ClassVar[DType]
|
||||
@@ -80,6 +87,10 @@ class ServingState(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
SERVING_STATE_NOT_SERVING: _ClassVar[ServingState]
|
||||
SCHEMA_VERSION_UNSPECIFIED: SchemaVersion
|
||||
SCHEMA_VERSION_1: SchemaVersion
|
||||
ARCHITECTURE_TYPE_UNSPECIFIED: ArchitectureType
|
||||
ARCHITECTURE_TYPE_DENSE: ArchitectureType
|
||||
ARCHITECTURE_TYPE_MOE: ArchitectureType
|
||||
ARCHITECTURE_TYPE_MLA: ArchitectureType
|
||||
DTYPE_UNSPECIFIED: DType
|
||||
DTYPE_BFLOAT16: DType
|
||||
DTYPE_FLOAT16: DType
|
||||
@@ -165,12 +176,16 @@ class NamedTensor(_message.Message):
|
||||
def __init__(self, name: _Optional[str] = ..., shape: _Optional[_Iterable[int]] = ..., dtype: _Optional[_Union[DType, str]] = ..., byte_order: _Optional[_Union[ByteOrder, str]] = ..., total_bytes: _Optional[int] = ..., compression: _Optional[_Union[Compression, str]] = ..., checksum: _Optional[_Union[Checksum, _Mapping]] = ..., fragments: _Optional[_Iterable[_Union[TensorFragment, _Mapping]]] = ...) -> None: ...
|
||||
|
||||
class TensorBundle(_message.Message):
|
||||
__slots__ = ("bundle_version", "tensors")
|
||||
__slots__ = ("bundle_version", "tensors", "architecture", "boundary_point")
|
||||
BUNDLE_VERSION_FIELD_NUMBER: _ClassVar[int]
|
||||
TENSORS_FIELD_NUMBER: _ClassVar[int]
|
||||
ARCHITECTURE_FIELD_NUMBER: _ClassVar[int]
|
||||
BOUNDARY_POINT_FIELD_NUMBER: _ClassVar[int]
|
||||
bundle_version: int
|
||||
tensors: _containers.RepeatedCompositeFieldContainer[NamedTensor]
|
||||
def __init__(self, bundle_version: _Optional[int] = ..., tensors: _Optional[_Iterable[_Union[NamedTensor, _Mapping]]] = ...) -> None: ...
|
||||
architecture: ArchitectureType
|
||||
boundary_point: str
|
||||
def __init__(self, bundle_version: _Optional[int] = ..., tensors: _Optional[_Iterable[_Union[NamedTensor, _Mapping]]] = ..., architecture: _Optional[_Union[ArchitectureType, str]] = ..., boundary_point: _Optional[str] = ...) -> None: ...
|
||||
|
||||
class Fingerprint(_message.Message):
|
||||
__slots__ = ("model_artifact_digest", "runtime_recipe_digest", "recipe_id", "recipe_version", "catalogue_version")
|
||||
@@ -327,20 +342,64 @@ class ActivationChunk(_message.Message):
|
||||
def __init__(self, envelope: _Optional[_Union[Envelope, _Mapping]] = ..., bundle: _Optional[_Union[TensorBundle, _Mapping]] = ...) -> None: ...
|
||||
|
||||
class DecodeStep(_message.Message):
|
||||
__slots__ = ("idempotency_step", "position", "expected_past_len", "tensor", "work_id", "deadline_unix_nanos")
|
||||
__slots__ = ("idempotency_step", "position", "expected_past_len", "tensor", "work_id", "deadline_unix_nanos", "bundle")
|
||||
IDEMPOTENCY_STEP_FIELD_NUMBER: _ClassVar[int]
|
||||
POSITION_FIELD_NUMBER: _ClassVar[int]
|
||||
EXPECTED_PAST_LEN_FIELD_NUMBER: _ClassVar[int]
|
||||
TENSOR_FIELD_NUMBER: _ClassVar[int]
|
||||
WORK_ID_FIELD_NUMBER: _ClassVar[int]
|
||||
DEADLINE_UNIX_NANOS_FIELD_NUMBER: _ClassVar[int]
|
||||
BUNDLE_FIELD_NUMBER: _ClassVar[int]
|
||||
idempotency_step: int
|
||||
position: int
|
||||
expected_past_len: int
|
||||
tensor: NamedTensor
|
||||
work_id: str
|
||||
deadline_unix_nanos: int
|
||||
def __init__(self, idempotency_step: _Optional[int] = ..., position: _Optional[int] = ..., expected_past_len: _Optional[int] = ..., tensor: _Optional[_Union[NamedTensor, _Mapping]] = ..., work_id: _Optional[str] = ..., deadline_unix_nanos: _Optional[int] = ...) -> None: ...
|
||||
bundle: TensorBundle
|
||||
def __init__(self, idempotency_step: _Optional[int] = ..., position: _Optional[int] = ..., expected_past_len: _Optional[int] = ..., tensor: _Optional[_Union[NamedTensor, _Mapping]] = ..., work_id: _Optional[str] = ..., deadline_unix_nanos: _Optional[int] = ..., bundle: _Optional[_Union[TensorBundle, _Mapping]] = ...) -> None: ...
|
||||
|
||||
class RequestRecipeIdentity(_message.Message):
|
||||
__slots__ = ("request_id", "runtime_recipe_digest", "chat_template_id", "chat_template_version", "reasoning_mode", "architecture")
|
||||
REQUEST_ID_FIELD_NUMBER: _ClassVar[int]
|
||||
RUNTIME_RECIPE_DIGEST_FIELD_NUMBER: _ClassVar[int]
|
||||
CHAT_TEMPLATE_ID_FIELD_NUMBER: _ClassVar[int]
|
||||
CHAT_TEMPLATE_VERSION_FIELD_NUMBER: _ClassVar[int]
|
||||
REASONING_MODE_FIELD_NUMBER: _ClassVar[int]
|
||||
ARCHITECTURE_FIELD_NUMBER: _ClassVar[int]
|
||||
request_id: str
|
||||
runtime_recipe_digest: str
|
||||
chat_template_id: str
|
||||
chat_template_version: str
|
||||
reasoning_mode: str
|
||||
architecture: ArchitectureType
|
||||
def __init__(self, request_id: _Optional[str] = ..., runtime_recipe_digest: _Optional[str] = ..., chat_template_id: _Optional[str] = ..., chat_template_version: _Optional[str] = ..., reasoning_mode: _Optional[str] = ..., architecture: _Optional[_Union[ArchitectureType, str]] = ...) -> None: ...
|
||||
|
||||
class SamplingParameters(_message.Message):
|
||||
__slots__ = ("temperature", "top_p", "top_k", "seed", "greedy")
|
||||
TEMPERATURE_FIELD_NUMBER: _ClassVar[int]
|
||||
TOP_P_FIELD_NUMBER: _ClassVar[int]
|
||||
TOP_K_FIELD_NUMBER: _ClassVar[int]
|
||||
SEED_FIELD_NUMBER: _ClassVar[int]
|
||||
GREEDY_FIELD_NUMBER: _ClassVar[int]
|
||||
temperature: float
|
||||
top_p: float
|
||||
top_k: int
|
||||
seed: int
|
||||
greedy: bool
|
||||
def __init__(self, temperature: _Optional[float] = ..., top_p: _Optional[float] = ..., top_k: _Optional[int] = ..., seed: _Optional[int] = ..., greedy: _Optional[bool] = ...) -> None: ...
|
||||
|
||||
class TailResult(_message.Message):
|
||||
__slots__ = ("identity", "sampling", "logits", "sampled_token_id")
|
||||
IDENTITY_FIELD_NUMBER: _ClassVar[int]
|
||||
SAMPLING_FIELD_NUMBER: _ClassVar[int]
|
||||
LOGITS_FIELD_NUMBER: _ClassVar[int]
|
||||
SAMPLED_TOKEN_ID_FIELD_NUMBER: _ClassVar[int]
|
||||
identity: RequestRecipeIdentity
|
||||
sampling: SamplingParameters
|
||||
logits: TensorBundle
|
||||
sampled_token_id: int
|
||||
def __init__(self, identity: _Optional[_Union[RequestRecipeIdentity, _Mapping]] = ..., sampling: _Optional[_Union[SamplingParameters, _Mapping]] = ..., logits: _Optional[_Union[TensorBundle, _Mapping]] = ..., sampled_token_id: _Optional[int] = ...) -> None: ...
|
||||
|
||||
class ReleaseSignal(_message.Message):
|
||||
__slots__ = ("route_session_id", "route_epoch", "work_id")
|
||||
@@ -409,18 +468,20 @@ class SessionRequest(_message.Message):
|
||||
def __init__(self, open: _Optional[_Union[SessionOpen, _Mapping]] = ..., chunk: _Optional[_Union[ActivationChunk, _Mapping]] = ..., decode: _Optional[_Union[DecodeStep, _Mapping]] = ..., flow_control: _Optional[_Union[FlowControl, _Mapping]] = ..., release: _Optional[_Union[ReleaseSignal, _Mapping]] = ..., cancel: _Optional[_Union[CancelSignal, _Mapping]] = ...) -> None: ...
|
||||
|
||||
class SessionResponse(_message.Message):
|
||||
__slots__ = ("accepted", "chunk", "ack", "flow_control", "status")
|
||||
__slots__ = ("accepted", "chunk", "ack", "flow_control", "status", "tail_result")
|
||||
ACCEPTED_FIELD_NUMBER: _ClassVar[int]
|
||||
CHUNK_FIELD_NUMBER: _ClassVar[int]
|
||||
ACK_FIELD_NUMBER: _ClassVar[int]
|
||||
FLOW_CONTROL_FIELD_NUMBER: _ClassVar[int]
|
||||
STATUS_FIELD_NUMBER: _ClassVar[int]
|
||||
TAIL_RESULT_FIELD_NUMBER: _ClassVar[int]
|
||||
accepted: SessionAccepted
|
||||
chunk: ActivationChunk
|
||||
ack: Ack
|
||||
flow_control: FlowControl
|
||||
status: ShardStatus
|
||||
def __init__(self, accepted: _Optional[_Union[SessionAccepted, _Mapping]] = ..., chunk: _Optional[_Union[ActivationChunk, _Mapping]] = ..., ack: _Optional[_Union[Ack, _Mapping]] = ..., flow_control: _Optional[_Union[FlowControl, _Mapping]] = ..., status: _Optional[_Union[ShardStatus, _Mapping]] = ...) -> None: ...
|
||||
tail_result: TailResult
|
||||
def __init__(self, accepted: _Optional[_Union[SessionAccepted, _Mapping]] = ..., chunk: _Optional[_Union[ActivationChunk, _Mapping]] = ..., ack: _Optional[_Union[Ack, _Mapping]] = ..., flow_control: _Optional[_Union[FlowControl, _Mapping]] = ..., status: _Optional[_Union[ShardStatus, _Mapping]] = ..., tail_result: _Optional[_Union[TailResult, _Mapping]] = ...) -> None: ...
|
||||
|
||||
class CapabilityRequest(_message.Message):
|
||||
__slots__ = ("schema_version",)
|
||||
|
||||
Reference in New Issue
Block a user