Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions crates/apr-cli/src/commands/chat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ use aprender::serialization::apr::AprReader;
// asking…` on Qwen3-1.7B. Two functions with the same name, two enums, one of
// which could not express the right answer.
use colored::Colorize;
#[cfg(feature = "inference")]
use realizar::chat_template::{
auto_detect_template, detect_format_from_name, ChatMessage, ChatTemplateEngine, TemplateFormat,
};
Expand Down Expand Up @@ -682,7 +683,9 @@ fn print_welcome_banner(path: &Path, config: &ChatConfig) {
print_welcome_banner_for(path, detect_format(path), config);
}

fn print_welcome_banner_for(path: &Path, format: ModelFormat, config: &ChatConfig) {
/// The chat-template family the banner names, detected from the file name.
#[cfg(feature = "inference")]
fn banner_template_family(path: &Path) -> &'static str {
// Detect chat template format from model name (Toyota Way: Visual Control)
let model_name = path
.file_stem()
Expand All @@ -692,7 +695,18 @@ fn print_welcome_banner_for(path: &Path, format: ModelFormat, config: &ChatConfi
// #3801: ONE spelling of the name. This was a second copy of
// `template_format_name`, and two copies of a match over an enum are how a
// new variant gets handled in one place and not the other.
let template_name = crate::chat::realizar_chat::template_format_name(template_format);
crate::chat::realizar_chat::template_format_name(template_format)
}

/// #4972: without `inference` there is no template detector, and the session
/// refuses before its first turn.
#[cfg(not(feature = "inference"))]
fn banner_template_family(_path: &Path) -> &'static str {
"none: this apr was built without the `inference` feature"
}

fn print_welcome_banner_for(path: &Path, format: ModelFormat, config: &ChatConfig) {
let template_name = banner_template_family(path);

match format {
ModelFormat::Apr => {
Expand Down
2 changes: 1 addition & 1 deletion crates/apr-cli/src/commands/chat_generate_session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ struct ChatSession;

#[cfg(not(feature = "inference"))]
impl ChatSession {
fn new(_path: &Path) -> Result<Self, CliError> {
fn new(_path: &Path, _force_cpu: bool) -> Result<Self, CliError> {
Err(CliError::ValidationFailed(
"Chat requires the 'inference' feature (realizar). Rebuild with: \
cargo install --path crates/apr-cli --features inference"
Expand Down
4 changes: 4 additions & 0 deletions crates/apr-cli/src/commands/golden_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ fn thinking_on_budget_override() -> std::result::Result<Option<(usize, String)>,
/// One matched row of the `models` table. A row that declares no `budget`
/// REFUSES rather than inheriting the default, which was measured on a
/// different model (#3907).
#[cfg(feature = "inference")]
fn thinking_on_budget_row(
v: &serde_yaml::Value,
pat: &str,
Expand Down Expand Up @@ -385,6 +386,7 @@ fn thinking_on_budget_row(

/// The first `models` pattern that matches `model_file`, or `None` when the
/// model is unlisted and the `default` row applies.
#[cfg(feature = "inference")]
fn thinking_on_budget_match(
doc: &serde_yaml::Value,
model_file: &str,
Expand All @@ -400,6 +402,7 @@ fn thinking_on_budget_match(
}

/// The `default` row, for a model no pattern names.
#[cfg(feature = "inference")]
fn thinking_on_budget_default(
doc: &serde_yaml::Value,
) -> std::result::Result<(usize, String), String> {
Expand All @@ -418,6 +421,7 @@ fn thinking_on_budget_default(
Ok((usize::try_from(b).unwrap_or(0), format!("default: {basis}")))
}

#[cfg(feature = "inference")]
fn thinking_on_budget_for(model_file: &str) -> std::result::Result<(usize, String), String> {
if let Some(over) = thinking_on_budget_override()? {
return Ok(over);
Expand Down
1 change: 1 addition & 0 deletions crates/apr-cli/src/commands/output_verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1055,6 +1055,7 @@ fn run_golden_output_gate_runtime(
/// pass message's ON-leg clause (empty when the model has no thinking-on case), and
/// `Err(failed)` ends the gate. Extracted from `run_golden_output_gate_runtime` unchanged,
/// to keep that function under the complexity ratchet.
#[cfg(feature = "inference")]
fn runtime_thinking_on_leg(
path: &Path,
architecture: Option<&str>,
Expand Down
15 changes: 15 additions & 0 deletions crates/apr-cli/src/commands/run_entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ fn reconcile_and_emit(
/// (not a GGUF, a hub id rather than a path, an unreadable header), and an
/// unknown architecture is never refused — this predicate lists what we know we
/// did NOT build, never what we support.
#[cfg(feature = "inference")]
pub(crate) fn forced_accelerator_refusal(
accel_forced: bool,
architecture: Option<&str>,
Expand All @@ -222,6 +223,20 @@ pub(crate) fn forced_accelerator_refusal(
realizar::capability::no_cuda_forward_reason(architecture?)
}

/// #4972: a build without `inference` has no forward on any accelerator, so a
/// forced one is refused whatever the architecture, including an unread one.
#[cfg(not(feature = "inference"))]
pub(crate) fn forced_accelerator_refusal(
accel_forced: bool,
_architecture: Option<&str>,
) -> Option<String> {
accel_forced.then(|| {
"an accelerator was forced, but this apr was built without the `inference` \
feature, so it has no forward on any device (#4972)"
.to_string()
})
}

/// Read the declared architecture from a model path without loading it.
///
/// **A bounded PREFIX read, deliberately not an mmap.** The first draft called
Expand Down
25 changes: 24 additions & 1 deletion crates/apr-cli/src/commands/run_tests_accel_reconcile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ fn json_plus_benchmark_is_not_a_machine_surface() {
// #3817: --gpu on an architecture with no CUDA forward refuses BEFORE the load
// =============================================================================

#[cfg(test)]
#[cfg(all(test, feature = "inference"))]
mod forced_accelerator_refusal_tests {
use crate::commands::run::forced_accelerator_refusal;

Expand Down Expand Up @@ -280,6 +280,29 @@ mod forced_accelerator_refusal_tests {
}
}

/// #4972: without `inference` there is no forward on any device, so a forced
/// accelerator is refused for every architecture, an unread one included, and
/// an unforced run is never refused.
#[cfg(all(test, not(feature = "inference")))]
mod forced_accelerator_refusal_without_inference_tests {
use crate::commands::run::forced_accelerator_refusal;

#[test]
fn a_forced_accelerator_is_refused_for_every_architecture() {
for arch in [Some("qwen2"), Some("llama"), Some("qwen35moe"), None] {
let reason = forced_accelerator_refusal(true, arch)
.expect("a build without inference has no forward to reach");
assert!(reason.contains("inference"), "{reason}");
}
}

#[test]
fn an_unforced_run_is_not_refused() {
assert!(forced_accelerator_refusal(false, Some("qwen2")).is_none());
assert!(forced_accelerator_refusal(false, None).is_none());
}
}

// ── #3826: `fell_back` must name a fallback that HAPPENED ──────────────────
//
// `apr run --format json` reported `"fell_back": false` on a run whose own
Expand Down
1 change: 1 addition & 0 deletions crates/apr-cli/src/commands/serve/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub mod auth;
pub mod handlers;
#[cfg(feature = "inference")]
pub mod ollama;
#[cfg(feature = "inference")]
pub(crate) mod route_index;
pub mod routes;
#[cfg(feature = "inference")]
Expand Down
1 change: 1 addition & 0 deletions crates/apr-cli/src/dispatch_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ fn dispatch_analysis_commands_rest(cli: &Cli) -> Option<Result<(), CliError>> {
// complexity debt the pre-commit gate refuses to let any edit ride on.
#[cfg(feature = "inference")]
ExtendedCommands::Capability { json } => commands::capability::run(*json || cli.json),
#[cfg(feature = "inference")]
ExtendedCommands::Devices { json } => commands::devices::run(*json || cli.json),
ExtendedCommands::OtlpLint {
otlp_file,
Expand Down
28 changes: 14 additions & 14 deletions docs/audits/surface_audit.csv
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ apr,apr cgp profile wgpu,6,x86_64-linux,NONE,no,9,profiling,crates/aprender-cgp/
apr,apr cgp roofline,6,x86_64-linux,NONE,no,7,qa-cgp,crates/aprender-cgp/src/cli.rs:64,low
apr,apr cgp trace,6,x86_64-linux,NONE,no,7,qa-cgp,crates/aprender-cgp/src/cli.rs:99,low
apr,apr cgp tui,6,x86_64-linux,NONE,no,7,qa-cgp,crates/aprender-cgp/src/cli.rs:115,low
apr,apr chat,6,x86_64-linux,llama.cpp,yes,1,apr-lint-diag,crates/apr-cli/src/extended_commands.rs:40 (ACCELERATOR_GUARD crates/apr-cli/src/dispatch_analysis.rs:1710),high
apr,apr chat,6,x86_64-linux,llama.cpp,yes,1,apr-lint-diag,crates/apr-cli/src/extended_commands.rs:40 (ACCELERATOR_GUARD crates/apr-cli/src/dispatch_analysis.rs:1722),high
apr,apr chat --backend cpu,6,x86_64-linux,ollama,no,1,apr-lint-diag,crates/apr-cli/src/extended_commands.rs:85 (BACKEND_VALUES crates/apr-cli/src/commands_enum.rs:16),high
apr,apr chat --backend cuda,6,x86_64-linux;nvidia-cuda,ollama,no,1,apr-lint-diag,crates/apr-cli/src/extended_commands.rs:85 (BACKEND_VALUES crates/apr-cli/src/commands_enum.rs:16),medium
apr,apr chat --backend wgpu,6,UNKNOWN,ollama,no,1,apr-lint-diag,crates/apr-cli/src/extended_commands.rs:85 (BACKEND_VALUES crates/apr-cli/src/commands_enum.rs:16),high
Expand Down Expand Up @@ -184,16 +184,16 @@ apr,apr embed-viz-lint,1,x86_64-linux,NONE,yes,1,apr-lint-diag,crates/apr-cli/sr
apr,apr embeddings-lint,1,x86_64-linux,NONE,yes,1,apr-lint-diag,crates/apr-cli/src/extended_commands.rs:1173,high
apr,apr encrypt,4,x86_64-linux,NONE,yes,10,apr-core-commands,crates/apr-cli/src/tool_commands.rs:121,high
apr,apr eval,6,x86_64-linux,llama.cpp,yes,1,apr-lint-diag,crates/apr-cli/src/extended_commands.rs:124,high
apr,apr eval --task classify,6,x86_64-linux,scikit-learn,no,8,rag-eval,crates/apr-cli/src/dispatch_analysis.rs:1406 (flag crates/apr-cli/src/extended_commands.rs:145),high
apr,apr eval --task code,6,x86_64-linux,NONE,no,8,rag-eval,crates/apr-cli/src/dispatch_analysis.rs:1420 (flag crates/apr-cli/src/extended_commands.rs:145),high
apr,apr eval --task compare,6,x86_64-linux,NONE,no,8,rag-eval,crates/apr-cli/src/dispatch_analysis.rs:1444 (flag crates/apr-cli/src/extended_commands.rs:145),high
apr,apr eval --task contamination,6,x86_64-linux,huggingface-transformers,no,8,rag-eval,crates/apr-cli/src/dispatch_analysis.rs:1441 (flag crates/apr-cli/src/extended_commands.rs:145),high
apr,apr eval --task correlation,6,x86_64-linux,NONE,no,8,rag-eval,crates/apr-cli/src/dispatch_analysis.rs:1446 (flag crates/apr-cli/src/extended_commands.rs:145),high
apr,apr eval --task human,6,x86_64-linux,NONE,no,8,rag-eval,crates/apr-cli/src/dispatch_analysis.rs:1447 (flag crates/apr-cli/src/extended_commands.rs:145),high
apr,apr eval --task humaneval,6,x86_64-linux,NONE,no,8,rag-eval,crates/apr-cli/src/dispatch_analysis.rs:1423 (flag crates/apr-cli/src/extended_commands.rs:145),high
apr,apr eval --task mbpp,6,x86_64-linux,NONE,no,8,rag-eval,crates/apr-cli/src/dispatch_analysis.rs:1432 (flag crates/apr-cli/src/extended_commands.rs:145),high
apr,apr eval --task plan,6,x86_64-linux,NONE,no,8,rag-eval,crates/apr-cli/src/dispatch_analysis.rs:1448 (flag crates/apr-cli/src/extended_commands.rs:145),high
apr,apr eval --task verify,6,x86_64-linux,NONE,no,8,rag-eval,crates/apr-cli/src/dispatch_analysis.rs:1445 (flag crates/apr-cli/src/extended_commands.rs:145),high
apr,apr eval --task classify,6,x86_64-linux,scikit-learn,no,8,rag-eval,crates/apr-cli/src/dispatch_analysis.rs:1441 (flag crates/apr-cli/src/extended_commands.rs:145),high
apr,apr eval --task code,6,x86_64-linux,NONE,no,8,rag-eval,crates/apr-cli/src/dispatch_analysis.rs:1455 (flag crates/apr-cli/src/extended_commands.rs:145),high
apr,apr eval --task compare,6,x86_64-linux,NONE,no,8,rag-eval,crates/apr-cli/src/dispatch_analysis.rs:1479 (flag crates/apr-cli/src/extended_commands.rs:145),high
apr,apr eval --task contamination,6,x86_64-linux,huggingface-transformers,no,8,rag-eval,crates/apr-cli/src/dispatch_analysis.rs:1476 (flag crates/apr-cli/src/extended_commands.rs:145),high
apr,apr eval --task correlation,6,x86_64-linux,NONE,no,8,rag-eval,crates/apr-cli/src/dispatch_analysis.rs:1481 (flag crates/apr-cli/src/extended_commands.rs:145),high
apr,apr eval --task human,6,x86_64-linux,NONE,no,8,rag-eval,crates/apr-cli/src/dispatch_analysis.rs:1482 (flag crates/apr-cli/src/extended_commands.rs:145),high
apr,apr eval --task humaneval,6,x86_64-linux,NONE,no,8,rag-eval,crates/apr-cli/src/dispatch_analysis.rs:1458 (flag crates/apr-cli/src/extended_commands.rs:145),high
apr,apr eval --task mbpp,6,x86_64-linux,NONE,no,8,rag-eval,crates/apr-cli/src/dispatch_analysis.rs:1467 (flag crates/apr-cli/src/extended_commands.rs:145),high
apr,apr eval --task plan,6,x86_64-linux,NONE,no,8,rag-eval,crates/apr-cli/src/dispatch_analysis.rs:1483 (flag crates/apr-cli/src/extended_commands.rs:145),high
apr,apr eval --task verify,6,x86_64-linux,NONE,no,8,rag-eval,crates/apr-cli/src/dispatch_analysis.rs:1480 (flag crates/apr-cli/src/extended_commands.rs:145),high
apr,apr experiment view,6,x86_64-linux,pytorch,no,1,apr-lint-diag,crates/apr-cli/src/extended_commands.rs:1568,low
apr,apr explain,6,x86_64-linux,safetensors,yes,10,apr-core-commands,crates/apr-cli/src/commands_enum.rs:447,high
apr,apr explain-token-lint,1,x86_64-linux,NONE,yes,1,apr-lint-diag,crates/apr-cli/src/extended_commands.rs:1066,low
Expand Down Expand Up @@ -239,9 +239,9 @@ apr,apr oom-lint,1,x86_64-linux,NONE,yes,1,apr-lint-diag,crates/apr-cli/src/exte
apr,apr oracle,9,x86_64-linux,NONE,yes,10,apr-core-commands,crates/apr-cli/src/tool_commands.rs:84,medium
apr,apr otlp-lint,1,x86_64-linux,NONE,yes,1,apr-lint-diag,crates/apr-cli/src/extended_commands.rs:1108,high
apr,apr parity,9,x86_64-linux,NONE,yes,1,apr-lint-diag,crates/apr-cli/src/extended_commands.rs:317,medium
apr,apr parity --per-op,9,"x86_64-linux,aarch64-linux",NONE,no,1,apr-lint-diag,crates/apr-cli/src/extended_commands.rs:330 (dispatch crates/apr-cli/src/dispatch_analysis.rs:1516),high
apr,apr parity --out,7,"x86_64-linux,aarch64-linux",NONE,no,1,apr-lint-diag,crates/apr-cli/src/extended_commands.rs:333 (dispatch crates/apr-cli/src/dispatch_analysis.rs:1517),high
apr,apr parity --threshold,7,"x86_64-linux,aarch64-linux",NONE,no,1,apr-lint-diag,crates/apr-cli/src/extended_commands.rs:336 (dispatch crates/apr-cli/src/dispatch_analysis.rs:1517),high
apr,apr parity --per-op,9,"x86_64-linux,aarch64-linux",NONE,no,1,apr-lint-diag,crates/apr-cli/src/extended_commands.rs:330 (dispatch crates/apr-cli/src/dispatch_analysis.rs:1564),high
apr,apr parity --out,7,"x86_64-linux,aarch64-linux",NONE,no,1,apr-lint-diag,crates/apr-cli/src/extended_commands.rs:333 (dispatch crates/apr-cli/src/dispatch_analysis.rs:1564),high
apr,apr parity --threshold,7,"x86_64-linux,aarch64-linux",NONE,no,1,apr-lint-diag,crates/apr-cli/src/extended_commands.rs:336 (dispatch crates/apr-cli/src/dispatch_analysis.rs:1564),high
apr,apr pipeline apply,6,x86_64-linux,huggingface-transformers,no,10,apr-core-commands,crates/apr-cli/src/pipeline_commands.rs:28,low
apr,apr pipeline plan,6,x86_64-linux,huggingface-transformers,no,10,apr-core-commands,crates/apr-cli/src/pipeline_commands.rs:9,low
apr,apr pipeline status,6,x86_64-linux,huggingface-transformers,no,10,apr-core-commands,crates/apr-cli/src/pipeline_commands.rs:51,low
Expand Down
Loading