Component · L3
Inference Server
github.com/juanmmm21/llm-inference-server
A high-performance LLM inference server with token streaming and dynamic request batching.
- Lines
- 488
- Files
- 7
- Test files
- 1
- Commits
- 11
- Started
- 26 Jun 2026
- Last commit
- 6 Jul 2026
- Python 100%
● Where it sits
Layer 3 of AI Core — inference & control.
L1 Data & input
L2 Representation & retrieval
L3 Inference & control
L4 Agents
L5 MLOps & quality
↳ Flagship
README · 3 min read
Commits per day
High-performance inference server optimized for running causal language models. This module implements advanced concurrency management and throughput optimization techniques, specifically Dynamic Request Batching and token-by-token response streaming (Streaming) via Server-Sent Events (SSE).
The server is designed to be compatible both with local accelerators (MPS/CUDA) loading Hugging Face CausalLM models, and with offline environments with no GPU resources, thanks to a deterministic semantic fallback engine.
System Architecture and Dynamic Batching
The server's architecture is optimized to mitigate the traditional bottleneck in LLM inference: transferring weights from global memory (VRAM/RAM) to the processor's compute units (ALUs).
sequenceDiagram
autonumber
actor Cliente1 as Client A
actor Cliente2 as Client B
participant API as FastAPI Endpoint
participant Queue as asyncio.Queue
participant Worker as Batching Worker
participant Engine as Inference Engine
Client A->>API: POST /generate (Prompt A)
Note over API: Creates QueueItem with Future
API->>Queue: Enqueue QueueItem A
Note over Worker: Queue detects item.<br/>Starts 50ms window.
Client B->>API: POST /generate (Prompt B)
API->>Queue: Enqueue QueueItem B
Note over Worker: Window expires or batch full (Max 16).<br/>Pulls [A, B].
Worker->>Engine: generate_batch([Prompt A, Prompt B]) in ThreadPool
Note over Engine: Parallel inference (PyTorch / Fallback)
Engine-->>Worker: Returns [Text A, Text B]
Worker-->>API: Resolves Future A and Future B
API-->>Client A: HTTP Response (Text A)
API-->>Client B: HTTP Response (Text B)1. Dynamic Request Batching Mechanism
Instead of processing each inference request sequentially (incurring a critical overhead from loading the model weights on every query) or rejecting concurrent requests, the server implements a background asynchronous dispatcher:
- Asynchronous Enqueuing: Each incoming request to the
/generateendpoint creates aQueueItemstructure that encapsulates the prompt, the maximum number of tokens to generate, and anasyncio.Futureobject. The item is inserted into a thread-safeasyncio.Queue. - Batching Window: When an item enters the empty queue, the
dynamic_batch_workerwakes up and starts a configurable wait loop (). During this window, it non-blockingly collects all subsequent concurrent requests. - Batch Constraints: The worker stops accumulating items if the time window expires or if the batch reaches the maximum allowed size ().
- Execution in a Thread Pool Executor: Deep learning model inference blocks Python's Global Interpreter Lock (GIL) while doing heavy C++/CUDA computation. To avoid freezing FastAPI's async event loop, batch execution is delegated to an external executor via
loop.run_in_executor(None, engine.generate_batch, prompts, max_tokens). - Dispatch and Resolution: When batch inference finishes, the worker associates the decoded responses with their respective
Futures, notifying and releasing the suspended HTTP requests.
2. Inference Streaming via Server-Sent Events (SSE)
To optimize time to first token (TTFT), the /generate_stream endpoint exposes a persistent one-way connection using the Server-Sent Events (SSE) protocol. Token flow is managed as follows:
- The server initializes a generator that consumes the inference engine.
- On each generator iteration, a text fragment (token or subword) is emitted, encapsulated in a
token-type event structured as JSON:{ "event": "token", "id": "uuid-v4-identifier", "data": "next_word " } - When generation finishes, the stream sends a
"data": "[DONE]"control message with adoneevent and closes the connection safely.
3. Inference Engine and Offline Fallback
The InferenceEngine module handles hardware abstraction. It supports two operating modes:
- Online / Local Mode: Loads CausalLM-architecture models (e.g.
sshleifer/tiny-gpt2) via PyTorch and Transformers on the fastest compute platform available on the system (MPS on Apple Silicon hardware, CUDA on Nvidia systems, or CPU as a general fallback). - Simulation / Offline Fallback Mode: If the environment lacks GPU resources, a connection to download weights, or if compiler dependencies fail, a heuristic semantic engine kicks in. This engine analyzes the presence of key tokens in the prompt to structure coherent responses about AI concepts at a simulated generation rate (using random delays between
0.01and0.04seconds per word to replicate real streaming behavior).
Connection to the Ecosystem
Within the ai-core-infra suite, this server serves critical functions:
- semantic-model-router: The semantic router analyzes incoming client requests and redirects them to this inference server or to external proprietary APIs based on the query's complexity and sensitivity.
- orchestra-agents: Asynchronous agents and planners make recurring, concurrent queries to this module to resolve reflections, invoke tools, and synthesize observations without penalizing the main execution threads.
File Structure
inference_engine.py: Encapsulated module that handles loading the Hugging Face model, batch tokenization, hardware-accelerated inference, and offline simulation methods.server.py: FastAPI server definition, implementation of the dynamic dispatcher (dynamic_batch_worker) and the communication endpoints.test_server.py: Asynchronous unit test suite that validates batching's concurrent behavior, behavior under errors and cancelled threads, and correct operation of SSE streaming.example.py: Interactive client-server script that starts the FastAPI server, sends sequential requests, and simulates concurrent bursts to demonstrate dynamic batching while displaying live logs.
Installation and Serving
1. Install Dependencies
Make sure to enable the project's virtual environment before installing:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
2. Run Automated Tests
The test suite simulates the arrival of concurrent requests and verifies that they are correctly grouped and resolved in a single execution batch:
.venv/bin/python -m unittest test_server.py
3. Start the Local Server
You can start the FastAPI server directly using Uvicorn:
.venv/bin/python -m uvicorn server:app --host 127.0.0.1 --port 8000 --log-level info
4. Live Demonstration (Dynamic Batching)
With the server running in one terminal, run in another active terminal:
.venv/bin/python example.py
This script will fire multiple parallel calls asynchronously to observe dynamic batching reducing average latency and showing streaming output in the console.