feat: add configurations#57
Conversation
Signed-off-by: kerthcet <kerthcet@gmail.com>
There was a problem hiding this comment.
Pull request overview
This PR introduces a configurable inference engine configuration surface and wires it through both the CLI and API so defaults (especially the max-tokens budget) are no longer hardcoded.
Changes:
- Add
EngineConfigand plumb it intobackend::engine(...)so KV-cache sizing, block sizing, batching, and default token budget are configurable. - Add shared CLI engine-tuning flags for both
puma runandpuma serve, with docs describing the available options. - Update OpenAI-compatible API endpoints to use the engine’s configured default
max_tokenswhen requests omit it.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/cli/serve.rs | Passes an EngineConfig into engine construction for serve. |
| src/cli/commands.rs | Adds shared EngineArgs flags (flattened into run/serve) and tests for flag → config mapping. |
| src/backend/mod.rs | Re-exports EngineConfig from the backend module surface. |
| src/backend/llm_engine.rs | Introduces EngineConfig, threads it into engine(), and stores default_max_tokens on EngineHandle. |
| src/api/tests.rs | Updates API test harness to pass EngineConfig::default() into engine(). |
| src/api/completions.rs | Uses the engine’s configured default token budget when max_tokens is omitted. |
| src/api/chat.rs | Uses the engine’s configured default token budget when max_tokens is omitted (streaming + non-streaming). |
| README.md | Documents new engine-tuning usage and updates example commands/models. |
| docs/configuration.md | Adds documentation for engine-tuning flags and defaults. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (3)
src/cli/commands.rs:110
tokens_per_blockcan currently be set to 0 via CLI, butSequenceManager::newassertstokens_per_block > 0, so an invalid flag value will cause a runtime panic. Add a clap value parser/range to reject 0 at argument-parse time.
/// Size of a single KV block, in bytes (must be > 0)
#[arg(
long,
src/cli/commands.rs:114
max_batch_sizecan currently be set to 0 via CLI; inScheduler::schedule_prefillthis makes the prefill batch permanently "full" (len >= 0), so nothing ever schedules. Reject 0 at parse time with a clap range/value_parser.
value_parser = clap::value_parser!(usize).range(1..)
)]
block_size_bytes: usize,
src/backend/llm_engine.rs:408
engine()acceptsEngineConfigfrom both library callers and the CLI, but there are no invariants enforced here. Invalid values (e.g.,tokens_per_block == 0triggers an assert inSequenceManager::new;max_batch_size == 0stalls scheduling) will currently fail at runtime in less obvious places. Consider validatingEngineConfigat the start ofengine()to fail fast with a clear message.
config: EngineConfig,
) -> (EngineHandle, EngineRunner<B>) {
// KV-cache memory pool + block manager.
let allocator = Box::new(CpuAllocator::new(config.memory_pool_bytes));
let block_manager = BlockManager::new(allocator, config.block_size_bytes);
f33516d to
3afa889
Compare
|
/lgtm |
InftyAI-Agent
left a comment
There was a problem hiding this comment.
Approved: PR has both lgtm and approved labels
InftyAI-Agent
left a comment
There was a problem hiding this comment.
Approved: PR has both lgtm and approved labels
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (1)
src/backend/llm_engine.rs:408
EngineConfigdocuments constraints (e.g.,tokens_per_blockmust be > 0), butengine()doesn’t validate them. Passing an invalid config can cause panics deeper in the stack (e.g.,SequenceManager::newassertstokens_per_block > 0). Adding early validation here makes the public API safer and the failure mode clearer.
// KV-cache memory pool + block manager.
let allocator = Box::new(CpuAllocator::new(config.memory_pool_bytes));
let block_manager = BlockManager::new(allocator, config.block_size_bytes);
| req.max_tokens | ||
| .unwrap_or_else(|| engine.default_max_tokens()), |
| req.max_tokens | ||
| .unwrap_or_else(|| engine.default_max_tokens()), |
| req.max_tokens | ||
| .unwrap_or_else(|| engine.default_max_tokens()), |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (4)
src/api/completions.rs:79
engine.default_max_tokens()will never be used here if the request type still deserializesmax_tokenswith a default ofSome(100). CurrentlyChatCompletionRequest/CompletionRequestinsrc/api/types/request.rsuses#[serde(default = "default_max_tokens")]which setsmax_tokenstoSome(100)when the field is omitted, so this change won’t make the engine-configured default effective.
match engine
.generate(
&req.model,
&prompt,
req.max_tokens
.unwrap_or_else(|| engine.default_max_tokens()),
req.temperature.unwrap_or(0.7),
src/api/chat.rs:103
- This fallback to
engine.default_max_tokens()is likely unreachable in practice becauseChatCompletionRequest.max_tokensis deserialized with a default (#[serde(default = "default_max_tokens")]returningSome(100)). That means requests which omitmax_tokenswill still come through asSome(100), so the engine-configured default won’t apply.
let response = engine
.generate(
&req.model,
&prompt,
req.max_tokens
.unwrap_or_else(|| engine.default_max_tokens()),
req.temperature.unwrap_or(0.7),
)
src/api/chat.rs:176
- Same issue as the non-streaming path:
req.max_tokens.unwrap_or_else(|| engine.default_max_tokens())won’t use the engine default if the request struct is defaultingmax_tokenstoSome(100)on deserialization when the field is omitted.
match engine
.generate_stream(
&model,
&prompt,
req.max_tokens
.unwrap_or_else(|| engine.default_max_tokens()),
req.temperature.unwrap_or(0.7),
)
src/backend/llm_engine.rs:408
engine()now accepts a user-providedEngineConfig, but it doesn’t validate invariants (e.g.,tokens_per_block > 0). Passing0will currently panic insideSequenceManager::new(andblock_size_bytes == 0can result in zero-sized allocations). Adding explicit checks here provides a clearer failure mode and prevents accidental invalid configs from crashing the engine in less obvious places.
// KV-cache memory pool + block manager.
let allocator = Box::new(CpuAllocator::new(config.memory_pool_bytes));
let block_manager = BlockManager::new(allocator, config.block_size_bytes);
| - **`--tokens-per-block`** must be greater than `0`. | ||
| - **`--default-max-tokens`** only applies when a request omits `max_tokens`; an | ||
| explicit per-request `max_tokens` always takes precedence. |
What this PR does / why we need it
Which issue(s) this PR fixes
Fixes #
Special notes for your reviewer
Does this PR introduce a user-facing change?