| Title: | Read 'GGUF' Model Files into 'Rfmalloc'-Backed Arrays |
|---|---|
| Description: | Reads 'GGUF' model files, the file format used by the 'llama.cpp' project (<https://github.com/ggerganov/llama.cpp>) to store large language model tensors and metadata, and exposes their tensors directly as 'Rfmalloc'-backed, file-backed ALTREP matrices and arrays. Quantized tensor types supported by the vendored 'gguflib' parser (<https://github.com/antirez/gguf-tools>) are dequantized on demand. Metadata key-value pairs and the tensor directory are exposed as ordinary R lists and data frames. A minimal writer is included to create 'GGUF' files containing 32-bit floating point tensors, primarily to support round-trip testing. |
| Authors: | Sounkou Mahamane Toure [aut, cre], Salvatore Sanfilippo [cph] (gguf-tools/gguflib), Georgi Gerganov [cph] (GGUF format enums/structures adapted from ggml) |
| Maintainer: | Sounkou Mahamane Toure <[email protected]> |
| License: | GPL (>= 2) |
| Version: | 0.1.0 |
| Built: | 2026-07-07 21:23:01 UTC |
| Source: | https://github.com/sounkou-bioinfo/Rfmalloc |
Reads some or all tensors from a GGUF file into a named list of
Rfmalloc-backed matrices/arrays, dequantizing as needed. This is a
thin convenience wrapper around repeated gguf_tensor() calls that shares
a single open file handle across all of them.
gguf_import( path_or_ctx, tensors = NULL, runtime = NULL, as = c("numeric", "native") )gguf_import( path_or_ctx, tensors = NULL, runtime = NULL, as = c("numeric", "native") )
path_or_ctx |
Either a path to a GGUF file, or a |
tensors |
Optional character vector of tensor names to import. If
|
runtime |
Optional |
as |
Passed through to |
A named list of Rfmalloc-backed matrices/arrays, one per
imported tensor, in the order requested (or file order, if tensors is
NULL).
tmp <- tempfile(fileext = ".gguf") gguf_write_tensors(tmp, list( w1 = matrix(as.double(1:12), nrow = 4, ncol = 3), w2 = matrix(as.double(1:6), nrow = 3, ncol = 2) )) rt <- Rfmalloc::open_fmalloc(tempfile(fileext = ".bin")) mats <- gguf_import(tmp, runtime = rt) prod <- mats$w1 %*% mats$w2 Rfmalloc::is_fmalloc_vector(prod) unlink(tmp)tmp <- tempfile(fileext = ".gguf") gguf_write_tensors(tmp, list( w1 = matrix(as.double(1:12), nrow = 4, ncol = 3), w2 = matrix(as.double(1:6), nrow = 3, ncol = 2) )) rt <- Rfmalloc::open_fmalloc(tempfile(fileext = ".bin")) mats <- gguf_import(tmp, runtime = rt) prod <- mats$w1 %*% mats$w2 Rfmalloc::is_fmalloc_vector(prod) unlink(tmp)
Reads every metadata key-value pair from a GGUF file into a named R list.
gguf_metadata(x)gguf_metadata(x)
x |
Either a path to a GGUF file, or a |
Scalar values are converted to the closest native R type (integer for
8/16/32-bit signed and unsigned-but-int-safe integers, numeric for
32-bit unsigned and 64-bit integers/floats, logical for booleans, and
character for strings). Arrays of a supported scalar type become an R
vector of that type. A metadata value of a type this package does not
represent (there are none in the current GGUF spec, but the check is
defensive) is returned as NULL while keeping its name, rather than
raising an error.
A named list of metadata values, in file order.
tmp <- tempfile(fileext = ".gguf") gguf_write_tensors(tmp, list(w = matrix(1:6 + 0.5, nrow = 2)), metadata = list(name = "example", version = 1)) gguf_metadata(tmp) unlink(tmp)tmp <- tempfile(fileext = ".gguf") gguf_write_tensors(tmp, list(w = matrix(1:6 + 0.5, nrow = 2)), metadata = list(name = "example", version = 1)) gguf_metadata(tmp) unlink(tmp)
Opens a 'GGUF' model file and returns a lightweight context handle used by
gguf_metadata(), gguf_tensors(), gguf_tensor(), and gguf_import().
The file is memory-mapped by the vendored 'gguflib' parser and unmapped
automatically when the returned object is garbage collected, or earlier if
you call gguf_import()/friends with a plain file path (which open and
close their own short-lived context internally).
gguf_open(path)gguf_open(path)
path |
Character string giving the path to a GGUF file. |
The vendored parser memory-maps the file read/write (mmap(..., PROT_READ | PROT_WRITE, MAP_SHARED, ...)), so path must point to a writable
file even if you only intend to read tensors from it.
An object of class "gguf_ctx": an external pointer to the
underlying parser context, with a finalizer that closes it.
tmp <- tempfile(fileext = ".gguf") gguf_write_tensors(tmp, list(w = matrix(1:6 + 0.5, nrow = 2))) ctx <- gguf_open(tmp) gguf_tensors(ctx) unlink(tmp)tmp <- tempfile(fileext = ".gguf") gguf_write_tensors(tmp, list(w = matrix(1:6 + 0.5, nrow = 2))) ctx <- gguf_open(tmp) gguf_tensors(ctx) unlink(tmp)
Reads a single named tensor from a GGUF file, dequantizing it if needed, into a fresh Rfmalloc-backed ALTREP matrix or array of doubles.
gguf_tensor(x, name, runtime = NULL, as = c("numeric", "native"))gguf_tensor(x, name, runtime = NULL, as = c("numeric", "native"))
x |
Either a path to a GGUF file, or a |
name |
Tensor name, as it appears in |
runtime |
Optional |
as |
|
GGUF tensor dimensions are stored with dim[0] as the fastest-varying
(contiguous) dimension. R arrays are column-major, i.e. the first
dimension varies fastest, so dim[0] maps directly onto R's first
dimension with no transposition needed: dim(result) == c(dim[0], dim[1], ...). See inst/tinytest/test_gguf_roundtrip.R for a test that verifies
this mapping by writing known matrices/arrays and reading them back.
For as = "numeric", an Rfmalloc-backed ALTREP matrix (if the
tensor has 2 dimensions) or array (otherwise) of doubles, with dim()
equal to the tensor's GGUF dimensions in c(dim[0], dim[1], ...) order.
For as = "native", an fmalloc_tensor with the same dims.
tmp <- tempfile(fileext = ".gguf") gguf_write_tensors(tmp, list(w = matrix(1:6 + 0.5, nrow = 2))) rt <- Rfmalloc::open_fmalloc(tempfile(fileext = ".bin")) w <- gguf_tensor(tmp, "w", runtime = rt) w Rfmalloc::is_fmalloc_vector(w) unlink(tmp)tmp <- tempfile(fileext = ".gguf") gguf_write_tensors(tmp, list(w = matrix(1:6 + 0.5, nrow = 2))) rt <- Rfmalloc::open_fmalloc(tempfile(fileext = ".bin")) w <- gguf_tensor(tmp, "w", runtime = rt) w Rfmalloc::is_fmalloc_vector(w) unlink(tmp)
Lists the tensor directory of a GGUF file as a data frame, without reading or dequantizing any tensor payload.
gguf_tensors(x)gguf_tensors(x)
x |
Either a path to a GGUF file, or a |
A data frame with one row per tensor and columns:
Tensor name.
GGUF tensor type name, e.g. "f32", "q4_k".
Number of dimensions.
A list column; dims[[i]] is an integer vector of tensor
i's dimensions, GGUF-order (dim[0] first, the fastest-varying/
contiguous dimension, which gguf_tensor() maps to R's first,
column-major dimension).
Total number of scalar elements.
Size of the tensor's raw (possibly quantized) on-disk representation, in bytes.
Byte offset of the tensor data from the start of the file.
tmp <- tempfile(fileext = ".gguf") gguf_write_tensors(tmp, list(w = matrix(1:6 + 0.5, nrow = 2), b = 1:3 + 0.5)) gguf_tensors(tmp) unlink(tmp)tmp <- tempfile(fileext = ".gguf") gguf_write_tensors(tmp, list(w = matrix(1:6 + 0.5, nrow = 2), b = 1:3 + 0.5)) gguf_tensors(tmp) unlink(tmp)
Writes a named list of numeric vectors/matrices/arrays to a GGUF file as
32-bit floating point (f32) tensors, with optional simple metadata. This
is a minimal writer, primarily meant to build small GGUF fixtures for this
package's own round-trip tests without shipping binary test fixtures, but
it is exported since it is also useful on its own for producing test
fixtures for other GGUF consumers.
gguf_write_tensors(path, tensors, metadata = list())gguf_write_tensors(path, tensors, metadata = list())
path |
Character string giving the output file path. |
tensors |
A non-empty named list of numeric vectors, matrices, or arrays. Names become tensor names and must be unique and non-empty. |
metadata |
A named list of metadata key-value pairs to write. Each
value must be a single (length-1), non-missing string or numeric value;
numeric values are written as 64-bit floats ( |
Tensor dimensions are taken from each object's dim() (or its length()
for a plain vector, written as a 1-dimensional tensor) and stored in GGUF
dim[0]-fastest-varying order directly from R's column-major storage, so
gguf_tensor()/gguf_import() read back exactly the matrix/array you
wrote (see inst/tinytest/test_gguf_roundtrip.R).
Existing files at path are silently overwritten.
path, invisibly.
tmp <- tempfile(fileext = ".gguf") gguf_write_tensors(tmp, tensors = list(weight = matrix(1:6 + 0.5, nrow = 2)), metadata = list(name = "example-model", version = 1) ) gguf_tensors(tmp) unlink(tmp)tmp <- tempfile(fileext = ".gguf") gguf_write_tensors(tmp, tensors = list(weight = matrix(1:6 + 0.5, nrow = 2)), metadata = list(name = "example-model", version = 1) ) gguf_tensors(tmp) unlink(tmp)