[diffusion] api: add sampling parameters and model info endpoint to OpenAI API (#15071)
Co-authored-by: niehen6174 <niehen.6174@gmail.com> Co-authored-by: Mick <mickjagger19@icloud.com> Co-authored-by: niehen6174 <nihen6174@gmail.com>
This commit is contained in:
@@ -25,6 +25,33 @@ sglang serve "${SERVER_ARGS[@]}"
|
||||
- **--model-path**: Path to the model or model ID.
|
||||
- **--port**: HTTP port to listen on (default: `30000`).
|
||||
|
||||
#### Get Model Information
|
||||
|
||||
**Endpoint:** `GET /models`
|
||||
|
||||
Returns information about the model served by this server, including model path, task type, pipeline configuration, and precision settings.
|
||||
|
||||
**Curl Example:**
|
||||
|
||||
```bash
|
||||
curl -sS -X GET "http://localhost:30010/models"
|
||||
```
|
||||
|
||||
**Response Example:**
|
||||
|
||||
```json
|
||||
{
|
||||
"model_path": "Wan-AI/Wan2.1-T2V-1.3B-Diffusers",
|
||||
"task_type": "T2V",
|
||||
"workload_type": "serving",
|
||||
"pipeline_name": "wan_pipeline",
|
||||
"pipeline_class": "WanPipeline",
|
||||
"num_gpus": 4,
|
||||
"dit_precision": "bf16",
|
||||
"vae_precision": "fp16"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Endpoints
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import asyncio
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
from fastapi import APIRouter, FastAPI
|
||||
from fastapi import APIRouter, FastAPI, Request
|
||||
|
||||
from sglang.multimodal_gen.runtime.entrypoints.openai import image_api, video_api
|
||||
from sglang.multimodal_gen.runtime.server_args import ServerArgs
|
||||
@@ -40,6 +40,30 @@ async def health():
|
||||
return {"status": "ok"}
|
||||
|
||||
|
||||
@health_router.get("/models")
|
||||
async def get_models(request: Request):
|
||||
"""Get information about the model served by this server."""
|
||||
from sglang.multimodal_gen.registry import get_model_info
|
||||
|
||||
server_args: ServerArgs = request.app.state.server_args
|
||||
model_info = get_model_info(server_args.model_path)
|
||||
|
||||
response = {
|
||||
"model_path": server_args.model_path,
|
||||
"num_gpus": server_args.num_gpus,
|
||||
"task_type": server_args.pipeline_config.task_type.name,
|
||||
"dit_precision": server_args.pipeline_config.dit_precision,
|
||||
"vae_precision": server_args.pipeline_config.vae_precision,
|
||||
"workload_type": server_args.workload_type.value,
|
||||
}
|
||||
|
||||
if model_info:
|
||||
response["pipeline_name"] = model_info.pipeline_cls.pipeline_name
|
||||
response["pipeline_class"] = model_info.pipeline_cls.__name__
|
||||
|
||||
return response
|
||||
|
||||
|
||||
@health_router.get("/health_generate")
|
||||
async def health_generate():
|
||||
# TODO : health generate endpoint
|
||||
|
||||
@@ -55,6 +55,10 @@ def _build_sampling_params_from_request(
|
||||
image_path: Optional[str] = None,
|
||||
seed: Optional[int] = None,
|
||||
generator_device: Optional[str] = None,
|
||||
negative_prompt: Optional[str] = None,
|
||||
guidance_scale: Optional[float] = None,
|
||||
num_inference_steps: Optional[int] = None,
|
||||
enable_teacache: Optional[bool] = None,
|
||||
) -> SamplingParams:
|
||||
if size is None:
|
||||
width, height = None, None
|
||||
@@ -77,6 +81,10 @@ def _build_sampling_params_from_request(
|
||||
output_file_name=f"{request_id}.{ext}",
|
||||
seed=seed,
|
||||
generator_device=generator_device,
|
||||
guidance_scale=guidance_scale,
|
||||
num_inference_steps=num_inference_steps,
|
||||
enable_teacache=enable_teacache,
|
||||
**({"negative_prompt": negative_prompt} if negative_prompt is not None else {}),
|
||||
)
|
||||
return sampling_params
|
||||
|
||||
@@ -118,6 +126,10 @@ async def generations(
|
||||
background=request.background,
|
||||
seed=request.seed,
|
||||
generator_device=request.generator_device,
|
||||
negative_prompt=request.negative_prompt,
|
||||
guidance_scale=request.guidance_scale,
|
||||
num_inference_steps=request.num_inference_steps,
|
||||
enable_teacache=request.enable_teacache,
|
||||
)
|
||||
batch = prepare_request(
|
||||
server_args=get_global_server_args(),
|
||||
@@ -169,6 +181,10 @@ async def edits(
|
||||
seed: Optional[int] = Form(1024),
|
||||
generator_device: Optional[str] = Form("cuda"),
|
||||
user: Optional[str] = Form(None),
|
||||
negative_prompt: Optional[str] = Form(None),
|
||||
guidance_scale: Optional[float] = Form(None),
|
||||
num_inference_steps: Optional[int] = Form(None),
|
||||
enable_teacache: Optional[bool] = Form(False),
|
||||
):
|
||||
request_id = generate_request_id()
|
||||
# Resolve images from either `image` or `image[]` (OpenAI SDK sends `image[]` when list is provided)
|
||||
@@ -198,6 +214,10 @@ async def edits(
|
||||
image_path=input_paths,
|
||||
seed=seed,
|
||||
generator_device=generator_device,
|
||||
negative_prompt=negative_prompt,
|
||||
guidance_scale=guidance_scale,
|
||||
num_inference_steps=num_inference_steps,
|
||||
enable_teacache=enable_teacache,
|
||||
)
|
||||
batch = _build_req_from_sampling(sampling)
|
||||
|
||||
|
||||
@@ -29,6 +29,10 @@ class ImageGenerationsRequest(BaseModel):
|
||||
seed: Optional[int] = 1024
|
||||
generator_device: Optional[str] = "cuda"
|
||||
user: Optional[str] = None
|
||||
negative_prompt: Optional[str] = None
|
||||
guidance_scale: Optional[float] = None
|
||||
num_inference_steps: Optional[int] = None
|
||||
enable_teacache: Optional[bool] = False
|
||||
|
||||
|
||||
# Video API protocol models
|
||||
@@ -62,6 +66,7 @@ class VideoGenerationsRequest(BaseModel):
|
||||
guidance_scale: Optional[float] = None
|
||||
guidance_scale_2: Optional[float] = None
|
||||
negative_prompt: Optional[str] = None
|
||||
enable_teacache: Optional[bool] = False
|
||||
|
||||
|
||||
class VideoListResponse(BaseModel):
|
||||
|
||||
@@ -82,6 +82,8 @@ def _build_sampling_params_from_request(
|
||||
sampling_kwargs["guidance_scale_2"] = request.guidance_scale_2
|
||||
if request.negative_prompt is not None:
|
||||
sampling_kwargs["negative_prompt"] = request.negative_prompt
|
||||
if request.enable_teacache is not None:
|
||||
sampling_kwargs["enable_teacache"] = request.enable_teacache
|
||||
sampling_params = SamplingParams.from_user_sampling_params_args(
|
||||
model_path=server_args.model_path,
|
||||
server_args=server_args,
|
||||
@@ -139,6 +141,12 @@ async def create_video(
|
||||
size: Optional[str] = Form(None),
|
||||
fps: Optional[int] = Form(None),
|
||||
num_frames: Optional[int] = Form(None),
|
||||
seed: Optional[int] = Form(1024),
|
||||
generator_device: Optional[str] = Form("cuda"),
|
||||
negative_prompt: Optional[str] = Form(None),
|
||||
guidance_scale: Optional[float] = Form(None),
|
||||
num_inference_steps: Optional[int] = Form(None),
|
||||
enable_teacache: Optional[bool] = Form(False),
|
||||
extra_body: Optional[str] = Form(None),
|
||||
):
|
||||
content_type = request.headers.get("content-type", "").lower()
|
||||
@@ -180,6 +188,12 @@ async def create_video(
|
||||
size=size,
|
||||
fps=fps_val,
|
||||
num_frames=num_frames_val,
|
||||
seed=seed,
|
||||
generator_device=generator_device,
|
||||
negative_prompt=negative_prompt,
|
||||
guidance_scale=guidance_scale,
|
||||
num_inference_steps=num_inference_steps,
|
||||
enable_teacache=enable_teacache,
|
||||
)
|
||||
else:
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user