main
py 124 lines 3.96 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import argparse
4 import asyncio
5 import signal
6 import socket
7 from argparse import Namespace
8
9 from vllm import AsyncEngineArgs, envs
10 from vllm.config import VllmConfig
11 from vllm.logger import configure_logging_from_args, init_logger
12
13 from ..app import build_app
14 from ..launcher import serve_http, setup_server
15 from ..utils.server_utils import get_uvicorn_log_config
16 from .app_state import init_render_app_state
17
18 logger = init_logger("vllm.entrypoints.launchers.render.entry")
19
20
21 async def build_and_serve_renderer(
22 vllm_config: VllmConfig,
23 listen_address: str,
24 sock: socket.socket,
25 args: Namespace,
26 **uvicorn_kwargs,
27 ) -> asyncio.Task:
28 """Build FastAPI app for a CPU-only render server, initialize state, and
29 start serving.
30
31 Returns the shutdown task for the caller to await.
32 """
33 # Get uvicorn log config (from file or with endpoint filter)
34 log_config = get_uvicorn_log_config(args)
35 if log_config is not None:
36 uvicorn_kwargs["log_config"] = log_config
37
38 app = build_app(args, ("render",))
39 await init_render_app_state(vllm_config, app.state, args)
40
41 logger.info("Starting vLLM server on %s", listen_address)
42
43 return await serve_http(
44 app,
45 sock=sock,
46 enable_ssl_refresh=args.enable_ssl_refresh,
47 host=args.host,
48 port=args.port,
49 log_level=args.uvicorn_log_level,
50 # NOTE: When the 'disable_uvicorn_access_log' value is True,
51 # no access log will be output.
52 access_log=not args.disable_uvicorn_access_log,
53 timeout_keep_alive=envs.VLLM_HTTP_TIMEOUT_KEEP_ALIVE,
54 ssl_keyfile=args.ssl_keyfile,
55 ssl_certfile=args.ssl_certfile,
56 ssl_ca_certs=args.ssl_ca_certs,
57 ssl_cert_reqs=args.ssl_cert_reqs,
58 ssl_ciphers=args.ssl_ciphers,
59 h11_max_incomplete_event_size=args.h11_max_incomplete_event_size,
60 h11_max_header_count=args.h11_max_header_count,
61 **uvicorn_kwargs,
62 )
63
64
65 async def run_launch_fastapi(args: argparse.Namespace) -> None:
66 """Run the online serving layer with FastAPI (no GPU inference)."""
67
68 # Interrupt initialization if SIGTERM arrives before uvicorn installs
69 # its own signal handlers. Once uvicorn is running it replaces this.
70 def _interrupt_init(*_) -> None:
71 raise KeyboardInterrupt("terminated")
72
73 signal.signal(signal.SIGTERM, _interrupt_init)
74
75 # 1. Socket binding
76 listen_address, sock = setup_server(args, reuse_port=False)
77
78 # 2. Build and serve the API server
79 engine_args = AsyncEngineArgs.from_cli_args(args)
80 model_config = engine_args.create_model_config()
81
82 # Render servers preprocess data only — no inference, no quantized kernels.
83 # Clear quantization so VllmConfig skips quant dtype/capability validation.
84 model_config.quantization = None
85
86 # Render servers never allocate KV cache; suppress the spurious CPU KV
87 # cache space warning from CpuPlatform.check_and_update_config.
88 envs.VLLM_CPU_KVCACHE_SPACE = 0
89
90 vllm_config = VllmConfig(
91 model_config=model_config,
92 logging_config=engine_args.create_logging_config(),
93 )
94 shutdown_task = await build_and_serve_renderer(
95 vllm_config, listen_address, sock, args
96 )
97 try:
98 await shutdown_task
99 finally:
100 sock.close()
101
102
103 if __name__ == "__main__":
104 import uvloop
105
106 from vllm.entrypoints.serve.utils.api_utils import cli_env_setup
107 from vllm.utils.argparse_utils import FlexibleArgumentParser
108
109 from ..cli_args import (
110 make_arg_parser,
111 validate_parsed_serve_args,
112 )
113
114 cli_env_setup()
115 parser = FlexibleArgumentParser(
116 description="Starts a GPU-less rendering server "
117 "for preprocessing and postprocessing only"
118 )
119 parser = make_arg_parser(parser)
120 args = parser.parse_args()
121 configure_logging_from_args(args)
122 validate_parsed_serve_args(args)
123
124 uvloop.run(run_launch_fastapi(args))