[misc] Deep-merge nested config overrides and parse request bodies with orjson (#33351)
This commit is contained in:
@@ -42,6 +42,7 @@ from typing import (
|
|||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
import orjson
|
||||||
import requests
|
import requests
|
||||||
import uvicorn
|
import uvicorn
|
||||||
import uvloop
|
import uvloop
|
||||||
@@ -60,6 +61,7 @@ from fastapi import (
|
|||||||
from fastapi.exceptions import RequestValidationError
|
from fastapi.exceptions import RequestValidationError
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
from fastapi.responses import ORJSONResponse, Response, StreamingResponse
|
from fastapi.responses import ORJSONResponse, Response, StreamingResponse
|
||||||
|
from fastapi.routing import APIRoute
|
||||||
|
|
||||||
from sglang.srt.configs.embedding_model_spec import resolved_embedding_plan
|
from sglang.srt.configs.embedding_model_spec import resolved_embedding_plan
|
||||||
from sglang.srt.constants import HEALTH_CHECK_RID_PREFIX
|
from sglang.srt.constants import HEALTH_CHECK_RID_PREFIX
|
||||||
@@ -427,10 +429,33 @@ async def lifespan(fast_api_app: FastAPI):
|
|||||||
|
|
||||||
|
|
||||||
# Fast API
|
# Fast API
|
||||||
|
class ORJSONRequest(Request):
|
||||||
|
"""Request whose ``json()`` uses orjson, for the tens-of-MB multimodal
|
||||||
|
bodies FastAPI would otherwise hand to stdlib json. Stricter than stdlib
|
||||||
|
on bare NaN/Infinity and >64-bit ints: those now 400 instead of parsing.
|
||||||
|
"""
|
||||||
|
|
||||||
|
async def json(self) -> Any:
|
||||||
|
if not hasattr(self, "_json"):
|
||||||
|
self._json = orjson.loads(await self.body())
|
||||||
|
return self._json
|
||||||
|
|
||||||
|
|
||||||
|
class ORJSONRoute(APIRoute):
|
||||||
|
def get_route_handler(self):
|
||||||
|
original_handler = super().get_route_handler()
|
||||||
|
|
||||||
|
async def custom_handler(request: Request):
|
||||||
|
return await original_handler(ORJSONRequest(request.scope, request.receive))
|
||||||
|
|
||||||
|
return custom_handler
|
||||||
|
|
||||||
|
|
||||||
app = FastAPI(
|
app = FastAPI(
|
||||||
lifespan=lifespan,
|
lifespan=lifespan,
|
||||||
openapi_url=None if get_bool_env_var("DISABLE_OPENAPI_DOC") else "/openapi.json",
|
openapi_url=None if get_bool_env_var("DISABLE_OPENAPI_DOC") else "/openapi.json",
|
||||||
)
|
)
|
||||||
|
app.router.route_class = ORJSONRoute
|
||||||
app.add_middleware(
|
app.add_middleware(
|
||||||
CORSMiddleware,
|
CORSMiddleware,
|
||||||
allow_origins=["*"],
|
allow_origins=["*"],
|
||||||
@@ -449,10 +474,13 @@ if envs.SGLANG_ENABLE_REQUEST_DECOMPRESSION.get():
|
|||||||
# Include routers
|
# Include routers
|
||||||
from sglang.srt.entrypoints.v1_loads import router as v1_loads_router
|
from sglang.srt.entrypoints.v1_loads import router as v1_loads_router
|
||||||
|
|
||||||
|
# route_class is per-router, so included routers need it set too.
|
||||||
|
v1_loads_router.route_class = ORJSONRoute
|
||||||
app.include_router(v1_loads_router)
|
app.include_router(v1_loads_router)
|
||||||
|
|
||||||
from sglang.srt.entrypoints.elastic_ep import router as elastic_ep_router
|
from sglang.srt.entrypoints.elastic_ep import router as elastic_ep_router
|
||||||
|
|
||||||
|
elastic_ep_router.route_class = ORJSONRoute
|
||||||
app.include_router(elastic_ep_router)
|
app.include_router(elastic_ep_router)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -254,7 +254,15 @@ def get_config(
|
|||||||
)
|
)
|
||||||
|
|
||||||
if model_override_args:
|
if model_override_args:
|
||||||
config.update(model_override_args)
|
# A plain update() setattrs a dict-valued override straight onto the
|
||||||
|
# config, so '{"text_config": {...}}' on a VLM would replace the whole
|
||||||
|
# sub-config with a dict and break attribute access downstream.
|
||||||
|
for key, value in model_override_args.items():
|
||||||
|
current = getattr(config, key, None)
|
||||||
|
if isinstance(value, dict) and isinstance(current, PretrainedConfig):
|
||||||
|
current.update(value)
|
||||||
|
else:
|
||||||
|
setattr(config, key, value)
|
||||||
|
|
||||||
if is_gguf:
|
if is_gguf:
|
||||||
if config.model_type not in MODEL_FOR_CAUSAL_LM_MAPPING_NAMES:
|
if config.model_type not in MODEL_FOR_CAUSAL_LM_MAPPING_NAMES:
|
||||||
|
|||||||
Reference in New Issue
Block a user