Skip to main content

llama_cpp_4/
lib.rs

1//! Bindings to the llama.cpp library.
2//!
3//! As llama.cpp is a very fast moving target, this crate does not attempt to create a stable API
4//! with all the rust idioms. Instead it provides safe wrappers around nearly direct bindings to
5//! llama.cpp. This makes it easier to keep up with the changes in llama.cpp, but does mean that
6//! the API is not as nice as it could be.
7//!
8//! # Quick start
9//!
10//! ```no_run
11//! use llama_cpp_4::prelude::*;
12//! use std::num::NonZeroU32;
13//!
14//! fn main() {
15//!     let backend = LlamaBackend::init().unwrap();
16//!     let model = LlamaModel::load_from_file(
17//!         &backend,
18//!         "model.gguf",
19//!         &LlamaModelParams::default(),
20//!     )
21//!     .unwrap();
22//!     let mut ctx = model
23//!         .new_context(
24//!             &backend,
25//!             LlamaContextParams::default().with_n_ctx(NonZeroU32::new(2048)),
26//!         )
27//!         .unwrap();
28//!
29//!     let tokens = model.str_to_token("Hello, world!", AddBos::Always).unwrap();
30//!     let mut batch = LlamaBatch::new(512, 1);
31//!     for (i, &tok) in tokens.iter().enumerate() {
32//!         batch
33//!             .add(tok, i as i32, &[0], i == tokens.len() - 1)
34//!             .unwrap();
35//!     }
36//!     ctx.decode(&mut batch).unwrap();
37//!
38//!     let token = LlamaSampler::greedy().sample(&ctx, 0);
39//!     let _piece = model.token_to_bytes(token, Special::Plaintext).unwrap();
40//! }
41//! ```
42//!
43//! # Examples in this repository
44//!
45//! - [simple](https://github.com/eugenehp/llama-cpp-rs/tree/main/examples/simple)
46//! - [chat](https://github.com/eugenehp/llama-cpp-rs/tree/main/examples/chat)
47//! - [embeddings](https://github.com/eugenehp/llama-cpp-rs/tree/main/examples/embeddings)
48//! - [server](https://github.com/eugenehp/llama-cpp-rs/tree/main/examples/server)
49//! - [mtp](https://github.com/eugenehp/llama-cpp-rs/tree/main/examples/mtp) — MTP speculative decoding via [`crate::mtp::MtpSession`]
50//! - [eagle](https://github.com/eugenehp/llama-cpp-rs/tree/main/examples/eagle) — EAGLE-3 speculative decoding via [`crate::eagle::Eagle3Session`]
51//!
52//! # Advanced: tensor capture
53//!
54//! Use [`TensorCapture`] with [`LlamaContextParams::with_tensor_capture`] to read
55//! per-layer hidden states (or other named graph nodes) during
56//! [`LlamaContext::decode`]. See [`context::tensor_capture`] for a full example.
57//!
58//! # Prelude
59//!
60//! For the types used in most inference programs, import [`prelude`]:
61//!
62//! ```
63//! use llama_cpp_4::prelude::*;
64//! ```
65//!
66//! The same core types are also re-exported at the crate root (e.g.
67//! [`LlamaModel`], [`LlamaBackend`]) so you can pick whichever import style
68//! you prefer. See [`prelude`] for a full list and additional examples (chat,
69//! embeddings, memory estimation).
70//!
71//! # Feature Flags
72//!
73//! - `cuda` enables CUDA GPU support.
74//! - `metal` enables Apple Metal GPU support.
75//! - `vulkan` enables Vulkan GPU support (AMD / Intel / cross-platform).
76//! - `native` enables host-CPU optimisations (`-march=native`).
77//! - `openmp` enables OpenMP multi-core CPU parallelism (on by default).
78//! - `rpc` enables RPC backend support for distributed inference across multiple machines.
79//! - `mtmd` enables multimodal (image + audio) support via `libmtmd`.
80use std::ffi::NulError;
81use std::fmt::Debug;
82use std::num::NonZeroI32;
83
84use crate::llama_batch::BatchAddError;
85use std::os::raw::c_int;
86use std::path::PathBuf;
87use std::string::FromUtf8Error;
88
89pub mod chat;
90pub mod common;
91pub mod common_sampler;
92pub mod context;
93pub mod eagle;
94pub mod fit;
95#[cfg(feature = "ggml")]
96pub mod ggml;
97pub mod llama_backend;
98pub mod llama_batch;
99pub mod model;
100pub mod mtp;
101pub mod ngram;
102pub mod prelude;
103pub mod quantize;
104pub mod runtime;
105pub mod sampling;
106// Plumbing shared by the shim-backed modules; not part of the public surface.
107mod shim;
108pub mod speculative;
109pub mod token;
110pub mod token_type;
111
112#[cfg(feature = "rpc")]
113pub mod rpc;
114
115#[cfg(feature = "mtmd")]
116pub mod mtmd;
117
118/// A failable result from a llama.cpp function.
119pub type Result<T> = std::result::Result<T, LLamaCppError>;
120
121/// All errors that can occur in the llama-cpp crate.
122#[derive(Debug, Eq, PartialEq, thiserror::Error)]
123pub enum LLamaCppError {
124    /// The backend was already initialized. This can generally be ignored as initializing the backend
125    /// is idempotent.
126    #[error("BackendAlreadyInitialized")]
127    BackendAlreadyInitialized,
128    /// There was an error while get the chat template from model.
129    #[error("{0}")]
130    ChatTemplateError(#[from] ChatTemplateError),
131    /// There was an error while decoding a batch.
132    #[error("{0}")]
133    DecodeError(#[from] DecodeError),
134    /// There was an error while encoding a batch.
135    #[error("{0}")]
136    EncodeError(#[from] EncodeError),
137    /// There was an error loading a model.
138    #[error("{0}")]
139    LlamaModelLoadError(#[from] LlamaModelLoadError),
140    /// There was an error creating a new model context.
141    #[error("{0}")]
142    LlamaContextLoadError(#[from] LlamaContextLoadError),
143    /// There was an error adding a token to a batch.
144    #[error["{0}"]]
145    BatchAddError(#[from] BatchAddError),
146    /// see [`EmbeddingsError`]
147    #[error(transparent)]
148    EmbeddingError(#[from] EmbeddingsError),
149}
150
151/// There was an error while getting the chat template from a model.
152#[derive(Debug, Eq, PartialEq, thiserror::Error)]
153pub enum ChatTemplateError {
154    /// the buffer was too small.
155    #[error("The buffer was too small. However, a buffer size of {0} would be just large enough.")]
156    BuffSizeError(usize),
157    /// gguf has no chat template
158    #[error("the model has no meta val - returned code {0}")]
159    MissingTemplate(i32),
160    /// The chat template was not valid utf8.
161    #[error(transparent)]
162    Utf8Error(#[from] std::str::Utf8Error),
163}
164
165/// Error retrieving a string from the model (e.g. description, metadata key/value).
166#[derive(Debug, Eq, PartialEq, thiserror::Error)]
167pub enum StringFromModelError {
168    /// The C function returned a negative error code.
169    #[error("llama.cpp returned error code {0}")]
170    ReturnedError(i32),
171    /// The returned bytes were not valid UTF-8.
172    #[error(transparent)]
173    Utf8Error(#[from] std::str::Utf8Error),
174}
175
176/// Failed to Load context
177#[derive(Debug, Eq, PartialEq, thiserror::Error)]
178pub enum LlamaContextLoadError {
179    /// llama.cpp returned null
180    #[error("null reference from llama.cpp")]
181    NullReturn,
182}
183
184/// Failed to decode a batch.
185#[derive(Debug, Eq, PartialEq, thiserror::Error)]
186pub enum DecodeError {
187    /// A Rust tensor callback failed or unwound after native execution began.
188    #[error(transparent)]
189    TensorCallback(#[from] context::TensorCallbackFailure),
190    /// No kv cache slot was available.
191    #[error("Decode Error 1: NoKvCacheSlot")]
192    NoKvCacheSlot,
193    /// The number of tokens in the batch was 0.
194    #[error("Decode Error -1: n_tokens == 0")]
195    NTokensZero,
196    /// A decode lifecycle hook vetoed the decode (native returned `-4`). The
197    /// specific cause is normally surfaced via [`DecodeError::TensorCallback`];
198    /// this is the fallback when no Rust-side failure was recorded.
199    #[error("Decode Error -4: vetoed by a decode lifecycle hook")]
200    VetoedByDecodeHook,
201    /// An unknown error occurred.
202    #[error("Decode Error {0}: unknown")]
203    Unknown(c_int),
204}
205
206/// Failed to decode a batch.
207#[derive(Debug, Eq, PartialEq, thiserror::Error)]
208pub enum EncodeError {
209    /// No kv cache slot was available.
210    #[error("Encode Error 1: NoKvCacheSlot")]
211    NoKvCacheSlot,
212    /// The number of tokens in the batch was 0.
213    #[error("Encode Error -1: n_tokens == 0")]
214    NTokensZero,
215    /// An unknown error occurred.
216    #[error("Encode Error {0}: unknown")]
217    Unknown(c_int),
218}
219
220/// When embedding related functions fail
221#[derive(Debug, Eq, PartialEq, thiserror::Error)]
222pub enum EmbeddingsError {
223    /// Embeddings weren't enabled in the context options
224    #[error("Embeddings weren't enabled in the context options")]
225    NotEnabled,
226    /// Logits weren't enabled for the given token
227    #[error("Logits were not enabled for the given token")]
228    LogitsNotEnabled,
229    /// The given sequence index exceeds the max sequence id
230    #[error("Can't use sequence embeddings with a model supporting only LLAMA_POOLING_TYPE_NONE")]
231    NonePoolType,
232}
233
234/// Decode a error from llama.cpp into a [`DecodeError`].
235impl From<NonZeroI32> for DecodeError {
236    fn from(value: NonZeroI32) -> Self {
237        match value.get() {
238            1 => DecodeError::NoKvCacheSlot,
239            -1 => DecodeError::NTokensZero,
240            -4 => DecodeError::VetoedByDecodeHook,
241            i => DecodeError::Unknown(i),
242        }
243    }
244}
245
246/// Encode a error from llama.cpp into a [`EncodeError`].
247impl From<NonZeroI32> for EncodeError {
248    fn from(value: NonZeroI32) -> Self {
249        match value.get() {
250            1 => EncodeError::NoKvCacheSlot,
251            -1 => EncodeError::NTokensZero,
252            i => EncodeError::Unknown(i),
253        }
254    }
255}
256
257/// An error that can occur when loading a model.
258#[derive(Debug, Eq, PartialEq, thiserror::Error)]
259pub enum LlamaModelLoadError {
260    /// There was a null byte in a provided string and thus it could not be converted to a C string.
261    #[error("null byte in string {0}")]
262    NullError(#[from] NulError),
263    /// llama.cpp returned a nullptr - this could be many different causes.
264    #[error("null result from llama cpp")]
265    NullResult,
266    /// Failed to convert the path to a rust str. This means the path was not valid unicode
267    #[error("failed to convert path {0} to str")]
268    PathToStrError(PathBuf),
269}
270
271/// An error that can occur when loading a model.
272#[derive(Debug, Eq, PartialEq, thiserror::Error)]
273pub enum LlamaLoraAdapterInitError {
274    /// There was a null byte in a provided string and thus it could not be converted to a C string.
275    #[error("null byte in string {0}")]
276    NullError(#[from] NulError),
277    /// llama.cpp returned a nullptr - this could be many different causes.
278    #[error("null result from llama cpp")]
279    NullResult,
280    /// Failed to convert the path to a rust str. This means the path was not valid unicode
281    #[error("failed to convert path {0} to str")]
282    PathToStrError(PathBuf),
283}
284
285/// An error that can occur when loading a model.
286#[derive(Debug, Eq, PartialEq, thiserror::Error)]
287pub enum LlamaLoraAdapterSetError {
288    /// llama.cpp returned a non-zero error code.
289    #[error("error code from llama cpp")]
290    ErrorResult(i32),
291}
292
293/// An error that can occur when loading a model.
294#[derive(Debug, Eq, PartialEq, thiserror::Error)]
295pub enum LlamaLoraAdapterRemoveError {
296    /// llama.cpp returned a non-zero error code.
297    #[error("error code from llama cpp")]
298    ErrorResult(i32),
299}
300
301/// get the time (in microseconds) according to llama.cpp
302/// ```
303/// # use llama_cpp_4::llama_time_us;
304/// let time = llama_time_us();
305/// assert!(time > 0);
306/// ```
307#[must_use]
308pub fn llama_time_us() -> i64 {
309    unsafe { llama_cpp_sys_4::llama_time_us() }
310}
311
312/// get the max number of devices according to llama.cpp (this is generally cuda devices)
313/// ```
314/// # use llama_cpp_4::max_devices;
315/// let max_devices = max_devices();
316/// assert!(max_devices >= 0);
317/// ```
318#[must_use]
319pub fn max_devices() -> usize {
320    unsafe { llama_cpp_sys_4::llama_max_devices() }
321}
322
323/// is memory mapping supported according to llama.cpp
324/// ```
325/// # use llama_cpp_4::mmap_supported;
326/// let mmap_supported = mmap_supported();
327/// if mmap_supported {
328///   println!("mmap_supported!");
329/// }
330/// ```
331#[must_use]
332pub fn mmap_supported() -> bool {
333    unsafe { llama_cpp_sys_4::llama_supports_mmap() }
334}
335
336/// is memory locking supported according to llama.cpp
337/// ```
338/// # use llama_cpp_4::mlock_supported;
339/// let mlock_supported = mlock_supported();
340/// if mlock_supported {
341///    println!("mlock_supported!");
342/// }
343/// ```
344#[must_use]
345pub fn mlock_supported() -> bool {
346    unsafe { llama_cpp_sys_4::llama_supports_mlock() }
347}
348
349/// An error that can occur when converting a token to a string.
350#[derive(Debug, thiserror::Error, Clone)]
351#[non_exhaustive]
352pub enum TokenToStringError {
353    /// the token type was unknown
354    #[error("Unknown Token Type")]
355    UnknownTokenType,
356    /// There was insufficient buffer space to convert the token to a string.
357    #[error("Insufficient Buffer Space {0}")]
358    InsufficientBufferSpace(c_int),
359    /// Caller-owned storage exceeds llama.cpp's signed buffer-length type.
360    #[error("piece buffer capacity {0} exceeds the native c_int bound")]
361    BufferCapacityExceeded(usize),
362    /// llama.cpp reported a positive piece length outside the supplied buffer.
363    #[error("native piece length {returned} exceeds buffer capacity {capacity}")]
364    NativePieceLength {
365        /// Positive length returned by llama.cpp.
366        returned: c_int,
367        /// Supplied caller-owned capacity.
368        capacity: usize,
369    },
370    /// The token was not valid utf8.
371    #[error("FromUtf8Error {0}")]
372    FromUtf8Error(#[from] FromUtf8Error),
373}
374
375/// Failed to convert a string to a token sequence.
376#[derive(Debug, thiserror::Error)]
377pub enum StringToTokenError {
378    /// the string contained a null byte and thus could not be converted to a c string.
379    #[error("{0}")]
380    NulError(#[from] NulError),
381    /// The string contained an interior NUL at the reported byte.
382    #[error("input contains an interior NUL at byte {0}")]
383    InteriorNul(usize),
384    #[error("{0}")]
385    /// Failed to convert a provided integer to a [`c_int`].
386    CIntConversionError(#[from] std::num::TryFromIntError),
387    /// llama.cpp reported a positive token count outside the supplied buffer.
388    #[error("native token count {returned} exceeds buffer capacity {capacity}")]
389    NativeTokenCount {
390        /// Positive count returned by llama.cpp.
391        returned: c_int,
392        /// Supplied caller-owned capacity.
393        capacity: usize,
394    },
395}
396
397/// Failed to apply model chat template.
398#[derive(Debug, thiserror::Error)]
399pub enum NewLlamaChatMessageError {
400    /// the string contained a null byte and thus could not be converted to a c string.
401    #[error("{0}")]
402    NulError(#[from] NulError),
403}
404
405/// Failed to apply model chat template.
406#[derive(Debug, thiserror::Error)]
407pub enum ApplyChatTemplateError {
408    /// the buffer was too small.
409    #[error("The buffer was too small. Please contact a maintainer and we will update it.")]
410    BuffSizeError,
411    /// the string contained a null byte and thus could not be converted to a c string.
412    #[error("{0}")]
413    NulError(#[from] NulError),
414    /// the string could not be converted to utf8.
415    #[error("{0}")]
416    FromUtf8Error(#[from] FromUtf8Error),
417}
418
419/// Get the time in microseconds according to ggml
420///
421/// ```
422/// # use std::time::Duration;
423/// use llama_cpp_4::ggml_time_us;
424///
425/// let start = ggml_time_us();
426///
427/// std::thread::sleep(Duration::from_micros(10));
428///
429/// let end = ggml_time_us();
430///
431/// let elapsed = end - start;
432///
433/// assert!(elapsed >= 10)
434#[must_use]
435pub fn ggml_time_us() -> i64 {
436    unsafe { llama_cpp_sys_4::ggml_time_us() }
437}
438
439/// Checks if mlock is supported.
440///
441/// ```
442/// # use llama_cpp_4::llama_supports_mlock;
443///
444/// if llama_supports_mlock() {
445///   println!("mlock is supported!");
446/// } else {
447///   println!("mlock is not supported!");
448/// }
449/// ```
450#[must_use]
451pub fn llama_supports_mlock() -> bool {
452    unsafe { llama_cpp_sys_4::llama_supports_mlock() }
453}
454
455/// Checks if GPU offload is supported.
456///
457/// Returns `true` if the library was compiled with GPU support (CUDA, Metal, Vulkan, etc.).
458#[must_use]
459pub fn supports_gpu_offload() -> bool {
460    unsafe { llama_cpp_sys_4::llama_supports_gpu_offload() }
461}
462
463/// Checks if RPC backend is supported.
464///
465/// Returns `true` if the library was compiled with RPC support.
466#[must_use]
467pub fn supports_rpc() -> bool {
468    unsafe { llama_cpp_sys_4::llama_supports_rpc() }
469}
470
471/// Version of the vendored llama.cpp this crate is linked against.
472///
473/// llama.cpp adopted semantic versioning in `b10470` / `v0.1.1`, so this is a
474/// `MAJOR.MINOR.PATCH` string (with a `-dev` suffix for builds off a
475/// non-release commit) rather than a `bNNNNN` build number. Useful for
476/// reporting the exact upstream a binary carries, since the crate version and
477/// the llama.cpp version move independently.
478///
479/// ```
480/// # use llama_cpp_4::llama_version;
481/// let version = llama_version();
482/// assert!(!version.is_empty());
483/// // e.g. "0.1.1"
484/// assert!(version.starts_with(char::is_numeric));
485/// ```
486///
487/// # Panics
488///
489/// Panics if the returned string is not valid UTF-8.
490#[must_use]
491pub fn llama_version() -> &'static str {
492    // SAFETY: llama.cpp returns a pointer to a string literal baked in at
493    // compile time, so it is non-null and lives for the life of the process.
494    let c_str = unsafe { std::ffi::CStr::from_ptr(llama_cpp_sys_4::llama_version()) };
495    c_str.to_str().expect("llama version is not valid UTF-8")
496}
497
498/// Get system information string.
499///
500/// Returns a string containing CPU features, build info, and other system details.
501///
502/// # Panics
503///
504/// Panics if the returned string is not valid UTF-8.
505#[must_use]
506pub fn print_system_info() -> String {
507    let c_str = unsafe { llama_cpp_sys_4::llama_print_system_info() };
508    let c_str = unsafe { std::ffi::CStr::from_ptr(c_str) };
509    c_str
510        .to_str()
511        .expect("system info is not valid UTF-8")
512        .to_owned()
513}
514
515/// Get the maximum number of parallel sequences supported.
516#[must_use]
517pub fn max_parallel_sequences() -> usize {
518    unsafe { llama_cpp_sys_4::llama_max_parallel_sequences() }
519}
520
521/// Get the maximum number of tensor buffer type overrides.
522#[must_use]
523pub fn max_tensor_buft_overrides() -> usize {
524    unsafe { llama_cpp_sys_4::llama_max_tensor_buft_overrides() }
525}
526
527/// Get the name of a flash attention type.
528///
529/// # Panics
530///
531/// Panics if the returned string is not valid UTF-8.
532#[must_use]
533pub fn flash_attn_type_name(flash_attn_type: i32) -> String {
534    let c_str = unsafe { llama_cpp_sys_4::llama_flash_attn_type_name(flash_attn_type) };
535    let c_str = unsafe { std::ffi::CStr::from_ptr(c_str) };
536    c_str
537        .to_str()
538        .expect("flash_attn_type_name is not valid UTF-8")
539        .to_owned()
540}
541
542/// Get the string representation of a model metadata key.
543///
544/// # Panics
545///
546/// Panics if the returned string is not valid UTF-8.
547#[must_use]
548pub fn model_meta_key_str(key: u32) -> String {
549    let c_str = unsafe { llama_cpp_sys_4::llama_model_meta_key_str(key as _) };
550    let c_str = unsafe { std::ffi::CStr::from_ptr(c_str) };
551    c_str
552        .to_str()
553        .expect("meta_key_str is not valid UTF-8")
554        .to_owned()
555}
556
557/// Quantize a model file using typed [`crate::quantize::QuantizeParams`].
558///
559/// Returns `Ok(())` on success, or `Err(code)` with the non-zero error code
560/// returned by `llama_model_quantize`.
561///
562/// # Panics
563///
564/// Panics if either path contains an interior null byte.
565///
566/// # Errors
567///
568/// Returns `Err(code)` with the non-zero status code from `llama_model_quantize`
569/// when quantization fails.
570///
571/// # Example
572///
573/// ```no_run
574/// use llama_cpp_4::quantize::{LlamaFtype, QuantizeParams};
575///
576/// let params = QuantizeParams::new(LlamaFtype::MostlyQ4KM)
577///     .with_nthread(8)
578///     .with_quantize_output_tensor(true);
579///
580/// llama_cpp_4::model_quantize("model-f16.gguf", "model-q4km.gguf", &params).unwrap();
581/// ```
582pub fn model_quantize(
583    fname_inp: &str,
584    fname_out: &str,
585    params: &quantize::QuantizeParams,
586) -> std::result::Result<(), u32> {
587    let c_inp = std::ffi::CString::new(fname_inp).expect("input path contains null bytes");
588    let c_out = std::ffi::CString::new(fname_out).expect("output path contains null bytes");
589    let guard = params.to_raw();
590    let rc = unsafe {
591        llama_cpp_sys_4::llama_model_quantize(c_inp.as_ptr(), c_out.as_ptr(), &raw const guard.raw)
592    };
593    if rc == 0 {
594        Ok(())
595    } else {
596        Err(rc)
597    }
598}
599
600/// Set the log callback.
601///
602/// # Safety
603///
604/// The callback and user data must remain valid for the lifetime of the application
605/// or until the callback is replaced.
606pub unsafe fn log_set(
607    callback: llama_cpp_sys_4::ggml_log_callback,
608    user_data: *mut std::ffi::c_void,
609) {
610    llama_cpp_sys_4::llama_log_set(callback, user_data);
611}
612
613/// Get the current log callback and user data.
614///
615/// # Safety
616///
617/// The caller must ensure the pointers are valid.
618pub unsafe fn log_get(
619    log_callback: *mut llama_cpp_sys_4::ggml_log_callback,
620    user_data: *mut *mut std::ffi::c_void,
621) {
622    llama_cpp_sys_4::llama_log_get(log_callback, user_data);
623}
624
625/// Initialize optimizer state for fine-tuning.
626///
627/// # Safety
628///
629/// The context and model must be valid and compatible.
630pub unsafe fn opt_init(
631    ctx: *mut llama_cpp_sys_4::llama_context,
632    model: *mut llama_cpp_sys_4::llama_model,
633    params: llama_cpp_sys_4::llama_opt_params,
634) {
635    llama_cpp_sys_4::llama_opt_init(ctx, model, params);
636}
637
638/// Run one training epoch.
639///
640/// # Safety
641///
642/// All pointers and handles must be valid.
643#[allow(clippy::too_many_arguments)]
644pub unsafe fn opt_epoch(
645    ctx: *mut llama_cpp_sys_4::llama_context,
646    dataset: llama_cpp_sys_4::ggml_opt_dataset_t,
647    result_train: llama_cpp_sys_4::ggml_opt_result_t,
648    result_eval: llama_cpp_sys_4::ggml_opt_result_t,
649    idata_split: i64,
650    callback_train: llama_cpp_sys_4::ggml_opt_epoch_callback,
651    callback_eval: llama_cpp_sys_4::ggml_opt_epoch_callback,
652) {
653    llama_cpp_sys_4::llama_opt_epoch(
654        ctx,
655        dataset,
656        result_train,
657        result_eval,
658        idata_split,
659        callback_train,
660        callback_eval,
661    );
662}
663
664/// Parameter filter that accepts all tensors (for use with [`opt_init`]).
665///
666/// # Safety
667///
668/// The tensor pointer must be valid.
669pub unsafe fn opt_param_filter_all(
670    tensor: *const llama_cpp_sys_4::ggml_tensor,
671    userdata: *mut std::ffi::c_void,
672) -> bool {
673    llama_cpp_sys_4::llama_opt_param_filter_all(tensor, userdata)
674}
675
676// ── Crate-root re-exports (see also [`prelude`]) ────────────────────────────
677//
678// These mirror the most common [`prelude`] exports so callers can write
679// `llama_cpp_4::LlamaModel` without a glob import.
680
681/// Parameters used when creating a context.
682pub use context::params::LlamaContextParams;
683/// One captured intermediate tensor from [`TensorCapture`].
684pub use context::CapturedTensor;
685/// Typed retained storage from an owned tensor transaction.
686pub use context::CapturedTensorData;
687/// An inference context tied to a model.
688pub use context::LlamaContext;
689/// Per-buffer memory usage entry from [`LlamaContext::memory_breakdown`].
690pub use context::MemoryBreakdownEntry;
691/// Access granted to an exact tensor selector.
692pub use context::TensorAccess;
693/// Exact sequence and causal-position metadata for one tensor row.
694pub use context::TensorBatchRow;
695/// A contained tensor callback failure.
696pub use context::TensorCallbackFailure;
697/// Hook `cb_eval` during decode to copy named graph tensors (layer hidden states, …).
698pub use context::TensorCapture;
699/// Typed Rust-owned tensor storage supplied to a transaction handler.
700pub use context::TensorDataMut;
701/// Element representation required by an exact tensor selector.
702pub use context::TensorElementType;
703pub use context::TensorFiniteValidation;
704/// Mapping between selected tensor rows and the decode batch.
705pub use context::TensorRowMapping;
706/// Exact bounded graph-node contract.
707pub use context::TensorSelector;
708/// Validated tensor dimensions.
709pub use context::TensorShape;
710/// One synchronous owned tensor transaction.
711pub use context::TensorTransaction;
712/// Error returned by a transaction handler or selector validator.
713pub use context::TensorTransactionError;
714/// Safe synchronous tensor transaction handler.
715pub use context::TensorTransactionHandler;
716/// Owned pinned tensor callback program.
717pub use context::TensorTransactions;
718/// Native write-back decision returned by a transaction handler.
719pub use context::TensorWriteback;
720/// Complete retained tensor from one transaction.
721pub use context::TransactionalTensorCapture;
722/// Initialise the llama.cpp backend and hardware drivers.
723pub use llama_backend::LlamaBackend;
724/// Micro-batch submitted to [`LlamaContext::decode`].
725pub use llama_batch::LlamaBatch;
726/// Parameters used when loading a model.
727pub use model::params::LlamaModelParams;
728/// Controls whether tokenisation prepends a BOS token.
729pub use model::AddBos;
730/// A loaded GGUF model.
731pub use model::LlamaModel;
732/// Controls how special tokens are rendered as text.
733pub use model::Special;
734/// Sampler chain for token selection.
735pub use sampling::LlamaSampler;
736/// Failure while capturing or restoring versioned speculative state.
737pub use speculative::SpeculativeStateError;
738/// A single vocabulary token id.
739pub use token::LlamaToken;