diff --git a/book/src/lib/autograd.md b/book/src/lib/autograd.md index 3ca5898eac..a32c05e074 100644 --- a/book/src/lib/autograd.md +++ b/book/src/lib/autograd.md @@ -10,6 +10,7 @@ Public module of the `aprender-core` crate. ## Example + ```rust use aprender::autograd::{Tensor, no_grad}; // See `cargo doc -p aprender-core --open` for full API reference. @@ -40,6 +41,7 @@ inspecting the graph, and the `GradFn` trait that custom ops implement. ### Pattern 1: A simple gradient computation + ```rust use aprender::autograd::Tensor; @@ -55,6 +57,7 @@ assert!((g.item() - 6.0).abs() < 1e-5); ### Pattern 2: Inference without graph overhead via `no_grad` + ```rust use aprender::autograd::{Tensor, no_grad, is_grad_enabled}; diff --git a/book/src/lib/classification.md b/book/src/lib/classification.md index 5f077dd991..f5784dfb84 100644 --- a/book/src/lib/classification.md +++ b/book/src/lib/classification.md @@ -10,6 +10,7 @@ Public module of the `aprender-core` crate. ## Example + ```rust use aprender::classification::LogisticRegression; // See `cargo doc -p aprender-core --open` for full API reference. @@ -38,6 +39,7 @@ the targets are discrete labels. ### Pattern 1: Logistic regression on separable data + ```rust use aprender::metrics::classification::accuracy; use aprender::prelude::*; @@ -61,6 +63,7 @@ println!("accuracy: {:.2}", acc); ### Pattern 2: KNN with custom distance metric + ```rust use aprender::classification::{DistanceMetric, KNearestNeighbors}; use aprender::primitives::Matrix; diff --git a/book/src/lib/format.md b/book/src/lib/format.md index e3708a66a5..25c0d53f01 100644 --- a/book/src/lib/format.md +++ b/book/src/lib/format.md @@ -10,6 +10,7 @@ Public module of the `aprender-core` crate. ## Example + ```rust use aprender::format::{ModelCard, AprConverter, ConvertOptions}; // See `cargo doc -p aprender-core --open` for full API reference. @@ -42,6 +43,7 @@ The submodules `quantize`, `gguf`, `onnx`, `sharded`, `signing`, and ### Pattern 1: Attach a model card to a checkpoint + ```rust use aprender::format::{ModelCard, TrainingDataInfo}; @@ -62,6 +64,7 @@ println!("model card: {}", card.name); ### Pattern 2: Diff two checkpoints tensor-by-tensor + ```rust use aprender::format::{DiffOptions, DiffCategory}; // AprConverter / diff_models work on real on-disk artefacts; diff --git a/book/src/lib/interpret.md b/book/src/lib/interpret.md index 146fb27245..af34dc28c7 100644 --- a/book/src/lib/interpret.md +++ b/book/src/lib/interpret.md @@ -40,6 +40,7 @@ make this prediction?" ### Pattern 1: Closed-form attribution for a linear model + ```rust use aprender::interpret::FeatureContributions; use aprender::primitives::Vector; @@ -61,6 +62,7 @@ assert!(contributions.verify_sum(1e-5)); ### Pattern 2: Permutation importance + ```rust use aprender::interpret::PermutationImportance; use aprender::primitives::Vector; diff --git a/book/src/lib/loss.md b/book/src/lib/loss.md index 222c6beef0..0f5b27c9d1 100644 --- a/book/src/lib/loss.md +++ b/book/src/lib/loss.md @@ -10,6 +10,7 @@ Public module of the `aprender-core` crate. ## Example + ```rust use aprender::loss::{MSELoss, MAELoss, HuberLoss, Loss}; // See `cargo doc -p aprender-core --open` for full API reference. @@ -37,6 +38,7 @@ passed around generically by optimizers and training loops. ### Pattern 1: Compute MSE and MAE on a single prediction vector + ```rust use aprender::loss::{mse_loss, mae_loss, huber_loss}; use aprender::primitives::Vector; @@ -54,6 +56,7 @@ assert!(mse > 0.0 && mae > 0.0); ### Pattern 2: Pass losses to generic code via the `Loss` trait + ```rust use aprender::loss::{Loss, MSELoss, HuberLoss}; use aprender::primitives::Vector; diff --git a/book/src/lib/model_selection.md b/book/src/lib/model_selection.md index 302e9c342b..e3e3e90503 100644 --- a/book/src/lib/model_selection.md +++ b/book/src/lib/model_selection.md @@ -10,6 +10,7 @@ Public module of the `aprender-core` crate. ## Example + ```rust use aprender::model_selection::{train_test_split, cross_validate, KFold, StratifiedKFold}; // See `cargo doc -p aprender-core --open` for full API reference. @@ -41,6 +42,7 @@ confidence intervals around your point estimates. ### Pattern 1: 5-fold cross-validation of a linear model + ```rust use aprender::model_selection::{cross_validate, KFold}; use aprender::prelude::*; @@ -58,6 +60,7 @@ println!("cv R²: mean={:.4} std={:.4}", result.mean(), result.std()); ### Pattern 2: Stratified split for classification + ```rust use aprender::model_selection::StratifiedKFold; use aprender::primitives::Vector; diff --git a/book/src/lib/models.md b/book/src/lib/models.md index 929d4a67fc..66be9c2547 100644 --- a/book/src/lib/models.md +++ b/book/src/lib/models.md @@ -10,6 +10,7 @@ Public module of the `aprender-core` crate. ## Example + ```rust use aprender::models::Qwen2Model; // See `cargo doc -p aprender-core --open` for full API reference. @@ -42,6 +43,7 @@ accessible so you can compose custom variants. ### Pattern 1: Construct a BERT encoder from a config + ```rust use aprender::models::{BertConfig, BertEncoder}; @@ -60,6 +62,7 @@ println!("encoder ready with {} layers", config.num_hidden_layers); ### Pattern 2: Inspect Qwen2 components + ```rust use aprender::models::qwen2::{Qwen2MLP, Embedding}; diff --git a/book/src/lib/nn.md b/book/src/lib/nn.md index a997e0de1f..0fd05bd64c 100644 --- a/book/src/lib/nn.md +++ b/book/src/lib/nn.md @@ -10,6 +10,7 @@ Public module of the `aprender-core` crate. ## Example + ```rust use aprender::nn::{Sequential, Linear, ReLU}; // See `cargo doc -p aprender-core --open` for full API reference. @@ -44,6 +45,7 @@ The submodule `nn::transformer` exposes attention + transformer-block types; ### Pattern 1: An MLP via `Sequential` + ```rust use aprender::nn::{Sequential, Linear, ReLU}; @@ -58,6 +60,7 @@ println!("layers: {}", model.len()); ### Pattern 2: Use RMSNorm (transformer-style) + ```rust use aprender::nn::{Linear, RMSNorm}; use aprender::nn::module::Module; diff --git a/book/src/lib/online.md b/book/src/lib/online.md index 7e8810fce7..d116dbc082 100644 --- a/book/src/lib/online.md +++ b/book/src/lib/online.md @@ -44,6 +44,7 @@ reinforcement learning from verifier (`rlvr`), and tokenizer surgery. ### Pattern 1: Streaming linear regression + ```rust use aprender::online::OnlineLinearRegression; @@ -66,6 +67,7 @@ for (x, _y) in &samples { ### Pattern 2: Logistic regression with configurable decay + ```rust use aprender::online::{OnlineLogisticRegression, OnlineLearnerConfig, LearningRateDecay}; diff --git a/book/src/lib/text.md b/book/src/lib/text.md index d3b72ad7b2..85ade3384d 100644 --- a/book/src/lib/text.md +++ b/book/src/lib/text.md @@ -10,6 +10,7 @@ Public module of the `aprender-core` crate. ## Example + ```rust use aprender::text::{Tokenizer, ChatTemplateEngine, ChatMessage}; // See `cargo doc -p aprender-core --open` for full API reference. @@ -40,6 +41,7 @@ templates a conversation runs through here. ### Pattern 1: Detect a chat template by model name + ```rust use aprender::text::{detect_format_from_name, TemplateFormat}; @@ -52,6 +54,7 @@ assert!(matches!(other, Some(TemplateFormat::Llama2))); ### Pattern 2: Render a multi-turn conversation + ```rust use aprender::text::{ChatMessage, ChatMLTemplate, ChatTemplateEngine}; diff --git a/scripts/_build_rust_compile_test.py b/scripts/_build_rust_compile_test.py index 875090dd6e..b7b2002e25 100755 --- a/scripts/_build_rust_compile_test.py +++ b/scripts/_build_rust_compile_test.py @@ -27,7 +27,9 @@ def extract() -> list[dict]: if not line.strip(): continue r = json.loads(line) - if r["lang"] == "rust" and r["path"].startswith("book/src/lib/"): + # Exclude rust blocks marked cost=skip (pending API alignment, etc.) + if r["lang"] == "rust" and r["path"].startswith("book/src/lib/") \ + and r.get("cost") != "skip": records.append(r) return records @@ -59,9 +61,14 @@ def main() -> int: "\n" "#![allow(dead_code, unused_imports, unused_variables)]\n" ) + seen: dict[str, int] = {} for r in records: stem = Path(r["path"]).stem # e.g. "active_learning" - mod_name = "block_" + sanitize_mod(stem) + base = "block_" + sanitize_mod(stem) + # Disambiguate: each rust block in the same chapter gets a unique mod name + n = seen.get(base, 0) + seen[base] = n + 1 + mod_name = base if n == 0 else f"{base}_{n}" lines.append(f"\n// from {r['path']} (lines {r['line_start']}..{r['line_end']})") lines.append(f"mod {mod_name} {{") lines.append(" #[allow(dead_code)]") diff --git a/scripts/extract_book_examples.py b/scripts/extract_book_examples.py index 788ba0844e..49829ed055 100755 --- a/scripts/extract_book_examples.py +++ b/scripts/extract_book_examples.py @@ -36,7 +36,7 @@ CLOSE_RE = re.compile(r"^```\s*$") COST_RE = re.compile(r"^\s*$") -VALID_COSTS = {"trivial", "model-required", "gpu", "destructive", "interactive"} +VALID_COSTS = {"trivial", "model-required", "gpu", "destructive", "interactive", "skip"} def parse_cost_annotation(line: str) -> tuple[str, str | None]: