[Cleanup] IPC struct renames, better typing, and SenderWrapper removal (#29214)
This commit is contained in:
@@ -28,6 +28,7 @@ import uuid
|
||||
from contextlib import asynccontextmanager
|
||||
from http import HTTPStatus
|
||||
from typing import (
|
||||
Annotated,
|
||||
Any,
|
||||
AsyncGenerator,
|
||||
AsyncIterator,
|
||||
@@ -43,6 +44,7 @@ import requests
|
||||
import uvicorn
|
||||
import uvloop
|
||||
from fastapi import (
|
||||
Body,
|
||||
Depends,
|
||||
FastAPI,
|
||||
File,
|
||||
@@ -739,7 +741,9 @@ async def get_load():
|
||||
# curl -s -X POST http://localhost:30000/set_internal_state -H "Content-Type: application/json" -d '{"server_args": {"pp_max_micro_batch_size": 8}}'
|
||||
@app.api_route("/set_internal_state", methods=["POST", "PUT"])
|
||||
@auth_level(AuthLevel.ADMIN_OPTIONAL)
|
||||
async def set_internal_state(obj: SetInternalStateReq, request: Request):
|
||||
async def set_internal_state(
|
||||
obj: Annotated[SetInternalStateReq, Body()], request: Request
|
||||
):
|
||||
res = await _global_state.tokenizer_manager.set_internal_state(obj)
|
||||
return res
|
||||
|
||||
@@ -950,7 +954,9 @@ async def clear_hicache_storage_backend():
|
||||
# }'
|
||||
@app.api_route("/hicache/storage-backend", methods=["PUT"])
|
||||
@auth_level(AuthLevel.ADMIN_OPTIONAL)
|
||||
async def attach_hicache_storage_backend(obj: AttachHiCacheStorageReqInput):
|
||||
async def attach_hicache_storage_backend(
|
||||
obj: Annotated[AttachHiCacheStorageReqInput, Body()],
|
||||
):
|
||||
"""Attach (enable) HiCache storage backend at runtime.
|
||||
|
||||
Only allowed when there are NO running / queued requests.
|
||||
@@ -964,7 +970,7 @@ async def attach_hicache_storage_backend(obj: AttachHiCacheStorageReqInput):
|
||||
hicache_storage_prefetch_policy=obj.hicache_storage_prefetch_policy,
|
||||
hicache_write_policy=obj.hicache_write_policy,
|
||||
)
|
||||
msg = getattr(ret, "message", "")
|
||||
msg = ret.message
|
||||
return Response(
|
||||
content=(
|
||||
(
|
||||
@@ -991,7 +997,7 @@ async def detach_hicache_storage_backend():
|
||||
return _admin_api_key_missing_response()
|
||||
|
||||
ret = await _global_state.tokenizer_manager.detach_hicache_storage()
|
||||
msg = getattr(ret, "message", "")
|
||||
msg = ret.message
|
||||
return Response(
|
||||
content=(
|
||||
(
|
||||
@@ -1024,7 +1030,7 @@ async def hicache_storage_backend_status():
|
||||
|
||||
@app.api_route("/start_profile", methods=["GET", "POST"])
|
||||
@auth_level(AuthLevel.ADMIN_OPTIONAL)
|
||||
async def start_profile_async(obj: Optional[ProfileReq] = None):
|
||||
async def start_profile_async(obj: Annotated[Optional[ProfileReq], Body()] = None):
|
||||
"""Start profiling."""
|
||||
await _global_state.tokenizer_manager.start_profile(obj or ProfileReq())
|
||||
return Response(
|
||||
@@ -1102,7 +1108,9 @@ async def dump_expert_distribution_record_async():
|
||||
|
||||
@app.post("/update_weights_from_disk")
|
||||
@auth_level(AuthLevel.ADMIN_OPTIONAL)
|
||||
async def update_weights_from_disk(obj: UpdateWeightFromDiskReqInput, request: Request):
|
||||
async def update_weights_from_disk(
|
||||
obj: Annotated[UpdateWeightFromDiskReqInput, Body()], request: Request
|
||||
):
|
||||
"""Update the weights from disk inplace without re-launching the server."""
|
||||
(
|
||||
success,
|
||||
@@ -1130,7 +1138,8 @@ async def update_weights_from_disk(obj: UpdateWeightFromDiskReqInput, request: R
|
||||
@app.post("/init_weights_send_group_for_remote_instance")
|
||||
@auth_level(AuthLevel.ADMIN_OPTIONAL)
|
||||
async def init_weights_send_group_for_remote_instance(
|
||||
obj: InitWeightsSendGroupForRemoteInstanceReqInput, request: Request
|
||||
obj: Annotated[InitWeightsSendGroupForRemoteInstanceReqInput, Body()],
|
||||
request: Request,
|
||||
):
|
||||
(
|
||||
success,
|
||||
@@ -1148,7 +1157,7 @@ async def init_weights_send_group_for_remote_instance(
|
||||
@app.post("/send_weights_to_remote_instance")
|
||||
@auth_level(AuthLevel.ADMIN_OPTIONAL)
|
||||
async def send_weights_to_remote_instance(
|
||||
obj: SendWeightsToRemoteInstanceReqInput, request: Request
|
||||
obj: Annotated[SendWeightsToRemoteInstanceReqInput, Body()], request: Request
|
||||
):
|
||||
(
|
||||
success,
|
||||
@@ -1204,7 +1213,7 @@ async def remote_instance_transfer_engine_info(rank: int = None):
|
||||
@app.post("/init_weights_update_group")
|
||||
@auth_level(AuthLevel.ADMIN_OPTIONAL)
|
||||
async def init_weights_update_group(
|
||||
obj: InitWeightsUpdateGroupReqInput, request: Request
|
||||
obj: Annotated[InitWeightsUpdateGroupReqInput, Body()], request: Request
|
||||
):
|
||||
"""Initialize the parameter update group."""
|
||||
success, message = await _global_state.tokenizer_manager.init_weights_update_group(
|
||||
@@ -1220,7 +1229,7 @@ async def init_weights_update_group(
|
||||
@app.post("/destroy_weights_update_group")
|
||||
@auth_level(AuthLevel.ADMIN_OPTIONAL)
|
||||
async def destroy_weights_update_group(
|
||||
obj: DestroyWeightsUpdateGroupReqInput, request: Request
|
||||
obj: Annotated[DestroyWeightsUpdateGroupReqInput, Body()], request: Request
|
||||
):
|
||||
"""Destroy the parameter update group."""
|
||||
(
|
||||
@@ -1236,7 +1245,7 @@ async def destroy_weights_update_group(
|
||||
@app.post("/update_weights_from_tensor")
|
||||
@auth_level(AuthLevel.ADMIN_OPTIONAL)
|
||||
async def update_weights_from_tensor(
|
||||
obj: UpdateWeightsFromTensorReqInput, request: Request
|
||||
obj: Annotated[UpdateWeightsFromTensorReqInput, Body()], request: Request
|
||||
):
|
||||
"""Update the weights from tensor inplace without re-launching the server.
|
||||
Notes:
|
||||
@@ -1258,7 +1267,7 @@ async def update_weights_from_tensor(
|
||||
@app.post("/update_weights_from_distributed")
|
||||
@auth_level(AuthLevel.ADMIN_OPTIONAL)
|
||||
async def update_weights_from_distributed(
|
||||
obj: UpdateWeightsFromDistributedReqInput, request: Request
|
||||
obj: Annotated[UpdateWeightsFromDistributedReqInput, Body()], request: Request
|
||||
):
|
||||
"""Update model parameter from distributed online."""
|
||||
(
|
||||
@@ -1277,7 +1286,9 @@ async def update_weights_from_distributed(
|
||||
|
||||
@app.post("/update_weights_from_ipc")
|
||||
@auth_level(AuthLevel.ADMIN_OPTIONAL)
|
||||
async def update_weights_from_ipc(obj: UpdateWeightsFromIPCReqInput, request: Request):
|
||||
async def update_weights_from_ipc(
|
||||
obj: Annotated[UpdateWeightsFromIPCReqInput, Body()], request: Request
|
||||
):
|
||||
"""Update the weights from IPC (Inter-Process Communication) for checkpoint-engine integration."""
|
||||
success, message = await _global_state.tokenizer_manager.update_weights_from_ipc(
|
||||
obj, request
|
||||
@@ -1294,7 +1305,9 @@ async def update_weights_from_ipc(obj: UpdateWeightsFromIPCReqInput, request: Re
|
||||
|
||||
@app.post("/update_weight_version")
|
||||
@auth_level(AuthLevel.ADMIN_OPTIONAL)
|
||||
async def update_weight_version(obj: UpdateWeightVersionReqInput, request: Request):
|
||||
async def update_weight_version(
|
||||
obj: Annotated[UpdateWeightVersionReqInput, Body()], request: Request
|
||||
):
|
||||
"""Update the weight version. This operation requires no active requests."""
|
||||
if obj.abort_all_requests:
|
||||
_global_state.tokenizer_manager.abort_request(abort_all=True)
|
||||
@@ -1325,7 +1338,9 @@ async def update_weight_version(obj: UpdateWeightVersionReqInput, request: Reque
|
||||
|
||||
@app.api_route("/get_weights_by_name", methods=["GET", "POST"])
|
||||
@auth_level(AuthLevel.ADMIN_OPTIONAL)
|
||||
async def get_weights_by_name(obj: GetWeightsByNameReqInput, request: Request):
|
||||
async def get_weights_by_name(
|
||||
obj: Annotated[GetWeightsByNameReqInput, Body()], request: Request
|
||||
):
|
||||
"""Get model parameter by name."""
|
||||
try:
|
||||
ret = await _global_state.tokenizer_manager.get_weights_by_name(obj, request)
|
||||
@@ -1340,7 +1355,7 @@ async def get_weights_by_name(obj: GetWeightsByNameReqInput, request: Request):
|
||||
@app.api_route("/release_memory_occupation", methods=["GET", "POST"])
|
||||
@auth_level(AuthLevel.ADMIN_OPTIONAL)
|
||||
async def release_memory_occupation(
|
||||
obj: ReleaseMemoryOccupationReqInput, request: Request
|
||||
obj: Annotated[ReleaseMemoryOccupationReqInput, Body()], request: Request
|
||||
):
|
||||
"""Release GPU memory occupation temporarily."""
|
||||
try:
|
||||
@@ -1352,7 +1367,7 @@ async def release_memory_occupation(
|
||||
@app.api_route("/resume_memory_occupation", methods=["GET", "POST"])
|
||||
@auth_level(AuthLevel.ADMIN_OPTIONAL)
|
||||
async def resume_memory_occupation(
|
||||
obj: ResumeMemoryOccupationReqInput, request: Request
|
||||
obj: Annotated[ResumeMemoryOccupationReqInput, Body()], request: Request
|
||||
):
|
||||
"""Resume GPU memory occupation."""
|
||||
try:
|
||||
@@ -1364,7 +1379,8 @@ async def resume_memory_occupation(
|
||||
@app.api_route("/weights_checker", methods=["GET", "POST"])
|
||||
@auth_level(AuthLevel.ADMIN_OPTIONAL)
|
||||
async def check_weights(
|
||||
obj: Optional[CheckWeightsReqInput] = None, request: Request = None
|
||||
obj: Annotated[Optional[CheckWeightsReqInput], Body()] = None,
|
||||
request: Request = None,
|
||||
):
|
||||
if obj is None:
|
||||
obj = CheckWeightsReqInput()
|
||||
@@ -1381,7 +1397,7 @@ async def check_weights(
|
||||
|
||||
@app.api_route("/slow_down", methods=["GET", "POST"])
|
||||
@auth_level(AuthLevel.ADMIN_OPTIONAL)
|
||||
async def slow_down(obj: SlowDownReqInput, request: Request):
|
||||
async def slow_down(obj: Annotated[SlowDownReqInput, Body()], request: Request):
|
||||
"""Slow down the system deliberately. Only for testing. Example scenario:
|
||||
when we want to test performance of D in large-scale PD disaggregation and have no enough nodes for P,
|
||||
we can use this to slow down D to let it have enough running sequences, and then disable slowdown
|
||||
@@ -1395,7 +1411,9 @@ async def slow_down(obj: SlowDownReqInput, request: Request):
|
||||
|
||||
@app.api_route("/load_lora_adapter", methods=["POST"])
|
||||
@auth_level(AuthLevel.ADMIN_OPTIONAL)
|
||||
async def load_lora_adapter(obj: LoadLoRAAdapterReqInput, request: Request):
|
||||
async def load_lora_adapter(
|
||||
obj: Annotated[LoadLoRAAdapterReqInput, Body()], request: Request
|
||||
):
|
||||
"""Load a new LoRA adapter without re-launching the server."""
|
||||
result = await _global_state.tokenizer_manager.load_lora_adapter(obj, request)
|
||||
|
||||
@@ -1413,7 +1431,7 @@ async def load_lora_adapter(obj: LoadLoRAAdapterReqInput, request: Request):
|
||||
|
||||
@app.api_route("/load_lora_adapter_from_tensors", methods=["POST"])
|
||||
async def load_lora_adapter_from_tensors(
|
||||
obj: LoadLoRAAdapterFromTensorsReqInput, request: Request
|
||||
obj: Annotated[LoadLoRAAdapterFromTensorsReqInput, Body()], request: Request
|
||||
):
|
||||
"""Load a new LoRA adapter from tensors without re-launching the server."""
|
||||
result = await _global_state.tokenizer_manager.load_lora_adapter_from_tensors(
|
||||
@@ -1428,7 +1446,9 @@ async def load_lora_adapter_from_tensors(
|
||||
|
||||
@app.api_route("/unload_lora_adapter", methods=["POST"])
|
||||
@auth_level(AuthLevel.ADMIN_OPTIONAL)
|
||||
async def unload_lora_adapter(obj: UnloadLoRAAdapterReqInput, request: Request):
|
||||
async def unload_lora_adapter(
|
||||
obj: Annotated[UnloadLoRAAdapterReqInput, Body()], request: Request
|
||||
):
|
||||
"""Load a new LoRA adapter without re-launching the server."""
|
||||
result = await _global_state.tokenizer_manager.unload_lora_adapter(obj, request)
|
||||
|
||||
@@ -1445,7 +1465,7 @@ async def unload_lora_adapter(obj: UnloadLoRAAdapterReqInput, request: Request):
|
||||
|
||||
|
||||
@app.api_route("/open_session", methods=["GET", "POST"])
|
||||
async def open_session(obj: OpenSessionReqInput, request: Request):
|
||||
async def open_session(obj: Annotated[OpenSessionReqInput, Body()], request: Request):
|
||||
"""Open a session, and return its unique session id."""
|
||||
try:
|
||||
session_id = await _global_state.tokenizer_manager.open_session(obj, request)
|
||||
@@ -1459,7 +1479,7 @@ async def open_session(obj: OpenSessionReqInput, request: Request):
|
||||
|
||||
|
||||
@app.api_route("/close_session", methods=["GET", "POST"])
|
||||
async def close_session(obj: CloseSessionReqInput, request: Request):
|
||||
async def close_session(obj: Annotated[CloseSessionReqInput, Body()], request: Request):
|
||||
"""Close the session."""
|
||||
try:
|
||||
await _global_state.tokenizer_manager.close_session(obj, request)
|
||||
@@ -1470,7 +1490,9 @@ async def close_session(obj: CloseSessionReqInput, request: Request):
|
||||
|
||||
@app.api_route("/configure_logging", methods=["GET", "POST"])
|
||||
@auth_level(AuthLevel.ADMIN_OPTIONAL)
|
||||
async def configure_logging(obj: ConfigureLoggingReq, request: Request):
|
||||
async def configure_logging(
|
||||
obj: Annotated[ConfigureLoggingReq, Body()], request: Request
|
||||
):
|
||||
"""Configure the request logging options."""
|
||||
_global_state.tokenizer_manager.configure_logging(obj)
|
||||
return Response(status_code=200)
|
||||
@@ -1478,7 +1500,7 @@ async def configure_logging(obj: ConfigureLoggingReq, request: Request):
|
||||
|
||||
@app.post("/abort_request")
|
||||
@auth_level(AuthLevel.ADMIN_OPTIONAL)
|
||||
async def abort_request(obj: AbortReq, request: Request):
|
||||
async def abort_request(obj: Annotated[AbortReq, Body()], request: Request):
|
||||
"""Abort a request."""
|
||||
try:
|
||||
_global_state.tokenizer_manager.abort_request(
|
||||
@@ -1490,7 +1512,9 @@ async def abort_request(obj: AbortReq, request: Request):
|
||||
|
||||
|
||||
@app.post("/parse_function_call")
|
||||
async def parse_function_call_request(obj: ParseFunctionCallReq, request: Request):
|
||||
async def parse_function_call_request(
|
||||
obj: Annotated[ParseFunctionCallReq, Body()], request: Request
|
||||
):
|
||||
"""
|
||||
A native API endpoint to parse function calls from a text.
|
||||
"""
|
||||
@@ -1512,7 +1536,9 @@ async def parse_function_call_request(obj: ParseFunctionCallReq, request: Reques
|
||||
|
||||
|
||||
@app.post("/separate_reasoning")
|
||||
async def separate_reasoning_request(obj: SeparateReasoningReqInput, request: Request):
|
||||
async def separate_reasoning_request(
|
||||
obj: Annotated[SeparateReasoningReqInput, Body()], request: Request
|
||||
):
|
||||
"""
|
||||
A native API endpoint to separate reasoning from a text.
|
||||
"""
|
||||
@@ -1520,7 +1546,7 @@ async def separate_reasoning_request(obj: SeparateReasoningReqInput, request: Re
|
||||
parser = ReasoningParser(model_type=obj.reasoning_parser, request=request)
|
||||
|
||||
# 2) Call the non-stream parsing method (non-stream)
|
||||
if getattr(obj, "return_blocks", False):
|
||||
if obj.return_blocks:
|
||||
blocks = parser.parse_non_stream_blocks(obj.text)
|
||||
reasoning_blocks = [b["text"] for b in blocks if b["type"] == "reasoning"]
|
||||
text_blocks = [b["text"] for b in blocks if b["type"] == "text"]
|
||||
@@ -1534,7 +1560,7 @@ async def separate_reasoning_request(obj: SeparateReasoningReqInput, request: Re
|
||||
"reasoning_text": reasoning_text,
|
||||
"text": normal_text,
|
||||
}
|
||||
if getattr(obj, "return_blocks", False):
|
||||
if obj.return_blocks:
|
||||
response_data["reasoning_blocks"] = reasoning_blocks
|
||||
response_data["text_blocks"] = text_blocks
|
||||
response_data["blocks"] = blocks
|
||||
@@ -1544,7 +1570,9 @@ async def separate_reasoning_request(obj: SeparateReasoningReqInput, request: Re
|
||||
|
||||
@app.post("/pause_generation")
|
||||
@auth_level(AuthLevel.ADMIN_OPTIONAL)
|
||||
async def pause_generation(obj: PauseGenerationReqInput, request: Request):
|
||||
async def pause_generation(
|
||||
obj: Annotated[PauseGenerationReqInput, Body()], request: Request
|
||||
):
|
||||
"""Pause generation."""
|
||||
await _global_state.tokenizer_manager.pause_generation(obj)
|
||||
return ORJSONResponse(
|
||||
@@ -1555,7 +1583,9 @@ async def pause_generation(obj: PauseGenerationReqInput, request: Request):
|
||||
|
||||
@app.post("/continue_generation")
|
||||
@auth_level(AuthLevel.ADMIN_OPTIONAL)
|
||||
async def continue_generation(obj: ContinueGenerationReqInput, request: Request):
|
||||
async def continue_generation(
|
||||
obj: Annotated[ContinueGenerationReqInput, Body()], request: Request
|
||||
):
|
||||
"""Continue generation."""
|
||||
await _global_state.tokenizer_manager.continue_generation(obj)
|
||||
return ORJSONResponse(
|
||||
@@ -1894,7 +1924,9 @@ async def sagemaker_chat_completions(
|
||||
|
||||
## Vertex AI API
|
||||
@app.post(os.environ.get("AIP_PREDICT_ROUTE", "/vertex_generate"))
|
||||
async def vertex_generate(vertex_req: VertexGenerateReqInput, raw_request: Request):
|
||||
async def vertex_generate(
|
||||
vertex_req: Annotated[VertexGenerateReqInput, Body()], raw_request: Request
|
||||
):
|
||||
if not vertex_req.instances:
|
||||
return []
|
||||
inputs = {}
|
||||
|
||||
Reference in New Issue
Block a user