Commit 3e41ae69d for llama.cpp
commit 3e41ae69dba547d27d37a9bdad8b087a85c792c1
Author: Yuri Khrustalev <ykhrustalev@users.noreply.github.com>
Date: Sat Nov 14 17:37:46 2026 -0500
llama : allocate the tensor staging buffer from the CPU buffer type (#31438)
* llama : allocate the tensor staging buffer from the CPU buffer type
* llama : drop the staging buffer test, reword the comment
diff --git a/src/llama-model-loader.cpp b/src/llama-model-loader.cpp
index 2cbee61d4..548ade101 100644
--- a/src/llama-model-loader.cpp
+++ b/src/llama-model-loader.cpp
@@ -1776,7 +1776,8 @@ bool llama_model_loader::load_all_data(
}
// staging buffer for non-host buffers without async uploads, reused because a fresh allocation per tensor page faults on every load
- std::vector<no_init<uint8_t>> read_buf;
+ // allocated from the CPU buffer type, which uses vm_allocate on Apple platforms, so freeing it returns its pages to the OS right away
+ ggml_backend_buffer_ptr read_buf;
for (struct ggml_tensor * cur : tensors) {
const auto * weight = get_weight(ggml_get_name(cur));
if (weight == nullptr) {
@@ -1904,12 +1905,16 @@ bool llama_model_loader::load_all_data(
const size_t buf_size = read_size + align - 1;
// tensors come biggest-first: shrink the buffer when it gets too large, so peak memory stays close to one tensor
- if (read_buf.size() < buf_size || read_buf.size() > 2*buf_size) {
- // free the old buffer first, `read_buf = {}` would keep its capacity
- read_buf = std::vector<no_init<uint8_t>>();
- read_buf.resize(buf_size);
+ const size_t read_buf_size = read_buf ? ggml_backend_buffer_get_size(read_buf.get()) : 0;
+ if (!read_buf || read_buf_size < buf_size || read_buf_size > 2*buf_size) {
+ // free the old buffer first, so only one is alive
+ read_buf.reset();
+ read_buf.reset(ggml_backend_buft_alloc_buffer(ggml_backend_cpu_buffer_type(), buf_size));
+ if (!read_buf) {
+ throw std::runtime_error(format("failed to allocate a %zu-byte staging buffer", buf_size));
+ }
}
- uint8_t * read_dst = (uint8_t *) GGML_PAD((uintptr_t) read_buf.data(), align);
+ uint8_t * read_dst = (uint8_t *) GGML_PAD((uintptr_t) ggml_backend_buffer_get_base(read_buf.get()), align);
file->seek(aligned_offset, SEEK_SET);
file->read_raw_unsafe(read_dst, read_size);