[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 numpy as np
|
||||
import orjson
|
||||
import requests
|
||||
import uvicorn
|
||||
import uvloop
|
||||
@@ -60,6 +61,7 @@ from fastapi import (
|
||||
from fastapi.exceptions import RequestValidationError
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
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.constants import HEALTH_CHECK_RID_PREFIX
|
||||
@@ -427,10 +429,33 @@ async def lifespan(fast_api_app: FastAPI):
|
||||
|
||||
|
||||
# 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(
|
||||
lifespan=lifespan,
|
||||
openapi_url=None if get_bool_env_var("DISABLE_OPENAPI_DOC") else "/openapi.json",
|
||||
)
|
||||
app.router.route_class = ORJSONRoute
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=["*"],
|
||||
@@ -449,10 +474,13 @@ if envs.SGLANG_ENABLE_REQUEST_DECOMPRESSION.get():
|
||||
# Include routers
|
||||
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)
|
||||
|
||||
from sglang.srt.entrypoints.elastic_ep import router as elastic_ep_router
|
||||
|
||||
elastic_ep_router.route_class = ORJSONRoute
|
||||
app.include_router(elastic_ep_router)
|
||||
|
||||
|
||||
|
||||
@@ -254,7 +254,15 @@ def get_config(
|
||||
)
|
||||
|
||||
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 config.model_type not in MODEL_FOR_CAUSAL_LM_MAPPING_NAMES:
|
||||
|
||||
Reference in New Issue
Block a user