"""CLI entry point: python -m replayer replay ...""" from __future__ import annotations import argparse import asyncio import logging from pathlib import Path from .replay import ReplayConfig, replay_trace def main() -> None: p = argparse.ArgumentParser(description="Trace replayer for vLLM benchmarking") p.add_argument("--trace", type=Path, required=True, help="Sampled trace JSONL") p.add_argument("--output", type=Path, required=True, help="Output metrics JSONL") p.add_argument("--endpoint", type=str, required=True, help="vLLM server URL (e.g. http://localhost:8000)") p.add_argument("--model", type=str, default="default", help="Model name for API") p.add_argument("--concurrency-limit", type=int, default=2000, help="Max concurrent HTTP requests (safety limit)") p.add_argument("--request-timeout", type=float, default=600.0) p.add_argument("--request-limit", type=int, default=None, help="Limit number of requests to replay") p.add_argument("-v", "--verbose", action="store_true") args = p.parse_args() logging.basicConfig( level=logging.DEBUG if args.verbose else logging.INFO, format="%(asctime)s %(levelname)s %(name)s: %(message)s", ) config = ReplayConfig( trace_path=args.trace, output_path=args.output, endpoint_url=args.endpoint.rstrip("/"), model_name=args.model, concurrency_limit=args.concurrency_limit, request_timeout_s=args.request_timeout, request_limit=args.request_limit, ) results = asyncio.run(replay_trace(config)) succeeded = sum(1 for r in results if r.error is None) print(f"\nDone: {succeeded}/{len(results)} requests succeeded") print(f"Metrics: {args.output}") print(f"Summary: {args.output.with_suffix('.summary.json')}") if __name__ == "__main__": main()