Integrate DS4 execution parity in Rust
This commit is contained in:
131
scripts/speculative_parity.py
Executable file
131
scripts/speculative_parity.py
Executable file
@@ -0,0 +1,131 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Compare DS4 and Rust endpoints configured for the same decoding mode."""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import urllib.request
|
||||
|
||||
|
||||
CASES = [
|
||||
"hi",
|
||||
"Reply with exactly three words describing a calm sea.",
|
||||
"Write the first eight positive odd numbers separated by commas.",
|
||||
]
|
||||
|
||||
|
||||
def post(base_url, path, payload):
|
||||
request = urllib.request.Request(
|
||||
base_url.rstrip("/") + path,
|
||||
data=json.dumps(payload).encode(),
|
||||
headers={"Content-Type": "application/json"},
|
||||
)
|
||||
with urllib.request.urlopen(request, timeout=600) as response:
|
||||
return json.load(response)
|
||||
|
||||
|
||||
def chat(base_url, prompt):
|
||||
result = post(
|
||||
base_url,
|
||||
"/v1/chat/completions",
|
||||
{
|
||||
"model": "deepseek-v4-flash",
|
||||
"messages": [{"role": "user", "content": prompt}],
|
||||
"reasoning_effort": "none",
|
||||
"temperature": 0,
|
||||
"max_tokens": 64,
|
||||
},
|
||||
)
|
||||
choice = result["choices"][0]
|
||||
message = choice["message"]
|
||||
return {
|
||||
"content": message.get("content"),
|
||||
"reasoning": message.get("reasoning_content"),
|
||||
"finish_reason": choice.get("finish_reason"),
|
||||
"usage": result.get("usage"),
|
||||
}
|
||||
|
||||
|
||||
def anthropic(base_url, prompt):
|
||||
result = post(
|
||||
base_url,
|
||||
"/v1/messages",
|
||||
{
|
||||
"model": "deepseek-v4-flash",
|
||||
"messages": [{"role": "user", "content": prompt}],
|
||||
"thinking": {"type": "disabled"},
|
||||
"temperature": 0,
|
||||
"max_tokens": 64,
|
||||
},
|
||||
)
|
||||
return {
|
||||
"content": result.get("content"),
|
||||
"stop_reason": result.get("stop_reason"),
|
||||
"usage": result.get("usage"),
|
||||
}
|
||||
|
||||
|
||||
def responses(base_url, prompt):
|
||||
result = post(
|
||||
base_url,
|
||||
"/v1/responses",
|
||||
{
|
||||
"model": "deepseek-v4-flash",
|
||||
"input": prompt,
|
||||
"reasoning": {"effort": "none"},
|
||||
"temperature": 0,
|
||||
"max_output_tokens": 64,
|
||||
},
|
||||
)
|
||||
return {
|
||||
"output": normalize(result.get("output")),
|
||||
"status": result.get("status"),
|
||||
"usage": result.get("usage"),
|
||||
}
|
||||
|
||||
|
||||
def normalize(value):
|
||||
if isinstance(value, list):
|
||||
return [normalize(item) for item in value]
|
||||
if isinstance(value, dict):
|
||||
return {
|
||||
key: normalize(item)
|
||||
for key, item in value.items()
|
||||
if key not in {"id", "created_at"}
|
||||
}
|
||||
return value
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("reference_url", help="DS4 reference server URL")
|
||||
parser.add_argument("rust_url", help="Rust DS4Server URL in the same mode")
|
||||
args = parser.parse_args()
|
||||
|
||||
failures = []
|
||||
for prompt in CASES:
|
||||
for name, request in (
|
||||
("chat", chat),
|
||||
("anthropic", anthropic),
|
||||
("responses", responses),
|
||||
):
|
||||
reference = request(args.reference_url, prompt)
|
||||
rust = request(args.rust_url, prompt)
|
||||
if reference != rust:
|
||||
failures.append(
|
||||
{
|
||||
"case": name,
|
||||
"prompt": prompt,
|
||||
"reference": reference,
|
||||
"rust": rust,
|
||||
}
|
||||
)
|
||||
else:
|
||||
print(f"ok {name}: {prompt}")
|
||||
if failures:
|
||||
print(json.dumps(failures, indent=2, ensure_ascii=False))
|
||||
raise SystemExit(1)
|
||||
print("all deterministic DS4/Rust endpoint outputs and usage records match")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user