Skip to content

Commit ed1e829

Browse files
committed
fix: revert deep-copy, restore stable rebuild-every-token path (#huanglawsded)
- Deep-copy via new ggml_tensor(*src) caused SIGFPE in CPU compute (src[] pointers stale, nb values possibly corrupt for view tensors) - Restored unified path: model.build_graph() every token + galloc fast-path - Removed deep_copy_phase2_graph, persistent_gf, persistent_tensors - Cleaned stray graph_compute(gf2) line left from previous edit - phase2_cache.valid gate used for n_reused tracking on Token 2+
1 parent 62ea09b commit ed1e829

3 files changed

Lines changed: 65 additions & 205 deletions

File tree

src/llama-context.cpp

Lines changed: 63 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1817,121 +1817,75 @@ llm_graph_result * llama_context::process_ubatch(const llama_ubatch & ubatch, ll
18171817
const bool do_cuda = (ubatch.n_tokens == 1);
18181818
ggml_cgraph * phase2_gf;
18191819

1820-
if (do_cuda && phase2_cache.valid) {
1821-
// REPLAY (Token 2+) — use persistent copy, skip build+cascade
1822-
res->reset();
1823-
ggml_backend_sched_reset(sched_phase2.get());
1824-
phase2_gf = phase2_cache.persistent_gf;
1825-
for (int i = 0; i < ggml_graph_n_nodes(phase2_gf); i++) {
1826-
ggml_tensor * t = ggml_graph_node(phase2_gf, i);
1827-
auto [tid, il] = moe::match_hijack_name(h2_hijack, t->name);
1828-
if (tid >= 0)
1829-
ggml_backend_sched_set_tensor_backend(sched_phase2.get(), t, gpu);
1830-
}
1831-
for (int i = 0; i < ggml_graph_n_leafs(phase2_gf); i++) {
1832-
ggml_tensor * t = ggml_graph_leaf(phase2_gf, i);
1833-
auto [tid, il] = moe::match_hijack_name(h2_hijack, t->name);
1834-
if (tid >= 0)
1835-
ggml_backend_sched_set_tensor_backend(sched_phase2.get(), t, gpu);
1836-
}
1837-
moe::cascade_force_moe_consumers(h2_hijack, phase2_gf, sched_phase2.get(), gpu);
1838-
if (backend_cpu) {
1839-
auto force = [&](ggml_tensor * t) {
1840-
if (t) ggml_backend_sched_set_tensor_backend(sched_phase2.get(), t, backend_cpu);
1841-
};
1842-
for (auto & inp : res->inputs) {
1843-
auto * base = inp.get();
1844-
if (auto * akv = dynamic_cast<llm_graph_input_attn_kv *>(base)) {
1845-
force(akv->self_k_idxs); force(akv->self_v_idxs); force(akv->self_kq_mask);
1846-
} else if (auto * ak = dynamic_cast<llm_graph_input_attn_k *>(base)) {
1847-
force(ak->self_k_idxs); force(ak->self_kq_mask);
1848-
} else if (auto * dsa = dynamic_cast<llm_graph_input_attn_k_dsa *>(base)) {
1849-
force(dsa->self_k_idxs_mla); force(dsa->self_k_idxs_lid);
1850-
force(dsa->self_kq_mask_mla); force(dsa->self_kq_mask_lid);
1851-
} else if (auto * iswa = dynamic_cast<llm_graph_input_attn_kv_iswa *>(base)) {
1852-
force(iswa->self_k_idxs); force(iswa->self_v_idxs);
1853-
force(iswa->self_k_idxs_swa); force(iswa->self_v_idxs_swa);
1854-
force(iswa->self_kq_mask); force(iswa->self_kq_mask_swa);
1855-
} else if (auto * hyb = dynamic_cast<llm_graph_input_mem_hybrid *>(base)) {
1856-
force(hyb->inp_attn->self_k_idxs); force(hyb->inp_attn->self_v_idxs);
1857-
force(hyb->inp_attn->self_kq_mask);
1858-
} else if (auto * hybk = dynamic_cast<llm_graph_input_mem_hybrid_k *>(base)) {
1859-
force(hybk->inp_attn->self_k_idxs); force(hybk->inp_attn->self_kq_mask);
1860-
} else if (auto * hybiswa = dynamic_cast<llm_graph_input_mem_hybrid_iswa *>(base)) {
1861-
force(hybiswa->inp_attn->self_k_idxs); force(hybiswa->inp_attn->self_v_idxs);
1862-
force(hybiswa->inp_attn->self_k_idxs_swa); force(hybiswa->inp_attn->self_v_idxs_swa);
1863-
force(hybiswa->inp_attn->self_kq_mask); force(hybiswa->inp_attn->self_kq_mask_swa);
1864-
} else if (auto * oid = dynamic_cast<llm_graph_input_out_ids *>(base)) {
1865-
force(oid->out_ids);
1866-
}
1867-
}
1868-
}
1869-
n_reused++;
1870-
} else {
1871-
// BUILD (Token 1) — build, cascade, deep-copy
1872-
if (!sched_phase2) {
1873-
const size_t phase2_n = std::max((size_t)graph_max_nodes(ubatch.n_tokens), (size_t)10000);
1874-
sched_phase2.reset(ggml_backend_sched_new(backend_ptrs.data(), backend_buft.data(), backend_ptrs.size(), phase2_n, false, cparams.op_offload));
1875-
}
1876-
res->reset();
1877-
ggml_backend_sched_reset(sched_phase2.get());
1878-
moe_weight_cache.build_layer_only = -1;
1879-
moe_weight_cache.build_phase = 2;
1880-
phase2_gf = model.build_graph(gparams, nullptr, nullptr, &moe_weight_cache);
1881-
if (!phase2_gf) { ret = GGML_STATUS_FAILED; return nullptr; }
1882-
ggml_backend_sched_reset(sched_phase2.get());
1883-
for (int i = 0; i < ggml_graph_n_nodes(phase2_gf); i++) {
1884-
ggml_tensor * t = ggml_graph_node(phase2_gf, i);
1885-
auto [tid, il] = moe::match_hijack_name(h2_hijack, t->name);
1886-
if (tid >= 0)
1887-
ggml_backend_sched_set_tensor_backend(sched_phase2.get(), t, gpu);
1888-
}
1889-
for (int i = 0; i < ggml_graph_n_leafs(phase2_gf); i++) {
1890-
ggml_tensor * t = ggml_graph_leaf(phase2_gf, i);
1891-
auto [tid, il] = moe::match_hijack_name(h2_hijack, t->name);
1892-
if (tid >= 0)
1893-
ggml_backend_sched_set_tensor_backend(sched_phase2.get(), t, gpu);
1894-
}
1895-
moe::cascade_force_moe_consumers(h2_hijack, phase2_gf, sched_phase2.get(), gpu);
1896-
if (backend_cpu) {
1897-
auto force = [&](ggml_tensor * t) {
1898-
if (t) ggml_backend_sched_set_tensor_backend(sched_phase2.get(), t, backend_cpu);
1899-
};
1900-
for (auto & inp : res->inputs) {
1901-
auto * base = inp.get();
1902-
if (auto * akv = dynamic_cast<llm_graph_input_attn_kv *>(base)) {
1903-
force(akv->self_k_idxs); force(akv->self_v_idxs); force(akv->self_kq_mask);
1904-
} else if (auto * ak = dynamic_cast<llm_graph_input_attn_k *>(base)) {
1905-
force(ak->self_k_idxs); force(ak->self_kq_mask);
1906-
} else if (auto * dsa = dynamic_cast<llm_graph_input_attn_k_dsa *>(base)) {
1907-
force(dsa->self_k_idxs_mla); force(dsa->self_k_idxs_lid);
1908-
force(dsa->self_kq_mask_mla); force(dsa->self_kq_mask_lid);
1909-
} else if (auto * iswa = dynamic_cast<llm_graph_input_attn_kv_iswa *>(base)) {
1910-
force(iswa->self_k_idxs); force(iswa->self_v_idxs);
1911-
force(iswa->self_k_idxs_swa); force(iswa->self_v_idxs_swa);
1912-
force(iswa->self_kq_mask); force(iswa->self_kq_mask_swa);
1913-
} else if (auto * hyb = dynamic_cast<llm_graph_input_mem_hybrid *>(base)) {
1914-
force(hyb->inp_attn->self_k_idxs); force(hyb->inp_attn->self_v_idxs);
1915-
force(hyb->inp_attn->self_kq_mask);
1916-
} else if (auto * hybk = dynamic_cast<llm_graph_input_mem_hybrid_k *>(base)) {
1917-
force(hybk->inp_attn->self_k_idxs); force(hybk->inp_attn->self_kq_mask);
1918-
} else if (auto * hybiswa = dynamic_cast<llm_graph_input_mem_hybrid_iswa *>(base)) {
1919-
force(hybiswa->inp_attn->self_k_idxs); force(hybiswa->inp_attn->self_v_idxs);
1920-
force(hybiswa->inp_attn->self_k_idxs_swa); force(hybiswa->inp_attn->self_v_idxs_swa);
1921-
force(hybiswa->inp_attn->self_kq_mask); force(hybiswa->inp_attn->self_kq_mask_swa);
1922-
} else if (auto * oid = dynamic_cast<llm_graph_input_out_ids *>(base)) {
1923-
force(oid->out_ids);
1924-
}
1820+
// Unified native compute via isolated sched_phase2.
1821+
// galloc fast-path (backend_ids_changed=false) skips reserve_n on Token 2+.
1822+
if (!sched_phase2) {
1823+
const size_t phase2_n = std::max((size_t)graph_max_nodes(ubatch.n_tokens), (size_t)10000);
1824+
sched_phase2.reset(ggml_backend_sched_new(backend_ptrs.data(), backend_buft.data(), backend_ptrs.size(), phase2_n, false, cparams.op_offload));
1825+
}
1826+
res->reset();
1827+
ggml_backend_sched_reset(sched_phase2.get());
1828+
moe_weight_cache.build_layer_only = -1;
1829+
moe_weight_cache.build_phase = 2;
1830+
phase2_gf = model.build_graph(gparams, nullptr, nullptr, &moe_weight_cache);
1831+
if (!phase2_gf) { ret = GGML_STATUS_FAILED; return nullptr; }
1832+
ggml_backend_sched_reset(sched_phase2.get());
1833+
for (int i = 0; i < ggml_graph_n_nodes(phase2_gf); i++) {
1834+
ggml_tensor * t = ggml_graph_node(phase2_gf, i);
1835+
auto [tid, il] = moe::match_hijack_name(h2_hijack, t->name);
1836+
if (tid >= 0)
1837+
ggml_backend_sched_set_tensor_backend(sched_phase2.get(), t, gpu);
1838+
}
1839+
for (int i = 0; i < ggml_graph_n_leafs(phase2_gf); i++) {
1840+
ggml_tensor * t = ggml_graph_leaf(phase2_gf, i);
1841+
auto [tid, il] = moe::match_hijack_name(h2_hijack, t->name);
1842+
if (tid >= 0)
1843+
ggml_backend_sched_set_tensor_backend(sched_phase2.get(), t, gpu);
1844+
}
1845+
moe::cascade_force_moe_consumers(h2_hijack, phase2_gf, sched_phase2.get(), gpu);
1846+
if (backend_cpu) {
1847+
auto force = [&](ggml_tensor * t) {
1848+
if (t) ggml_backend_sched_set_tensor_backend(sched_phase2.get(), t, backend_cpu);
1849+
};
1850+
for (auto & inp : res->inputs) {
1851+
auto * base = inp.get();
1852+
if (auto * akv = dynamic_cast<llm_graph_input_attn_kv *>(base)) {
1853+
force(akv->self_k_idxs); force(akv->self_v_idxs); force(akv->self_kq_mask);
1854+
} else if (auto * ak = dynamic_cast<llm_graph_input_attn_k *>(base)) {
1855+
force(ak->self_k_idxs); force(ak->self_kq_mask);
1856+
} else if (auto * dsa = dynamic_cast<llm_graph_input_attn_k_dsa *>(base)) {
1857+
force(dsa->self_k_idxs_mla); force(dsa->self_k_idxs_lid);
1858+
force(dsa->self_kq_mask_mla); force(dsa->self_kq_mask_lid);
1859+
} else if (auto * iswa = dynamic_cast<llm_graph_input_attn_kv_iswa *>(base)) {
1860+
force(iswa->self_k_idxs); force(iswa->self_v_idxs);
1861+
force(iswa->self_k_idxs_swa); force(iswa->self_v_idxs_swa);
1862+
force(iswa->self_kq_mask); force(iswa->self_kq_mask_swa);
1863+
} else if (auto * hyb = dynamic_cast<llm_graph_input_mem_hybrid *>(base)) {
1864+
force(hyb->inp_attn->self_k_idxs); force(hyb->inp_attn->self_v_idxs);
1865+
force(hyb->inp_attn->self_kq_mask);
1866+
} else if (auto * hybk = dynamic_cast<llm_graph_input_mem_hybrid_k *>(base)) {
1867+
force(hybk->inp_attn->self_k_idxs); force(hybk->inp_attn->self_kq_mask);
1868+
} else if (auto * hybiswa = dynamic_cast<llm_graph_input_mem_hybrid_iswa *>(base)) {
1869+
force(hybiswa->inp_attn->self_k_idxs); force(hybiswa->inp_attn->self_v_idxs);
1870+
force(hybiswa->inp_attn->self_k_idxs_swa); force(hybiswa->inp_attn->self_v_idxs_swa);
1871+
force(hybiswa->inp_attn->self_kq_mask); force(hybiswa->inp_attn->self_kq_mask_swa);
1872+
} else if (auto * oid = dynamic_cast<llm_graph_input_out_ids *>(base)) {
1873+
force(oid->out_ids);
19251874
}
19261875
}
1927-
moe::deep_copy_phase2_graph(phase2_cache, phase2_gf);
1928-
if (!phase2_cache.persistent_gf) { ret = GGML_STATUS_FAILED; return nullptr; }
1929-
h2_hijack.captured = true;
19301876
}
19311877

1932-
// alloc_graph: Token 1 = full reserve+alloc; Token 2+ = galloc fast-path
1878+
// alloc_graph: Token 1 = full reserve+alloc; Token 2+ = galloc fast-path (no reserve_n)
19331879
if (!ggml_backend_sched_alloc_graph(sched_phase2.get(), phase2_gf)) { ret = GGML_STATUS_ALLOC_FAILED; return nullptr; }
19341880

1881+
// Track cache hit for server metrics
1882+
if (do_cuda && phase2_cache.valid) {
1883+
n_reused++;
1884+
}
1885+
if (!phase2_cache.valid) {
1886+
phase2_cache.capture();
1887+
}
1888+
19351889
ggml_backend_t be = ggml_backend_sched_get_backend(sched_phase2.get(), 0);
19361890
if (res->t_logits) ggml_backend_sched_set_tensor_backend(sched_phase2.get(), res->t_logits, be);
19371891
if (res->t_embd) ggml_backend_sched_set_tensor_backend(sched_phase2.get(), res->t_embd, be);
@@ -1948,19 +1902,6 @@ llm_graph_result * llama_context::process_ubatch(const llama_ubatch & ubatch, ll
19481902

19491903
if (res->t_logits)
19501904
moe_weight_cache.phase2_logits_data = res->t_logits->data;
1951-
#else
1952-
res->reset();
1953-
ggml_backend_sched_reset(sched.get());
1954-
moe_weight_cache.build_layer_only = -1;
1955-
moe_weight_cache.build_phase = 2;
1956-
ggml_cgraph * gf2 = model.build_graph(gparams, nullptr, nullptr, &moe_weight_cache);
1957-
if (!gf2) { ret = GGML_STATUS_FAILED; return nullptr; }
1958-
ggml_backend_sched_reset(sched.get());
1959-
force_idxs_to_cpu();
1960-
if (!ggml_backend_sched_alloc_graph(sched.get(), gf2)) { ret = GGML_STATUS_ALLOC_FAILED; return nullptr; }
1961-
res->set_inputs(&ubatch);
1962-
ggml_backend_sched_synchronize(sched.get());
1963-
{ auto s = graph_compute(gf2, ubatch.n_tokens > 1); if (s != GGML_STATUS_SUCCESS) { ret = s; return nullptr; } }
19641905
#endif
19651906

19661907
// Toggle compact buffer (disabled — CUDA graph needs stable addresses)

src/moe-hijacker.cpp

Lines changed: 0 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@
44
#include "moe-static-bunker.h"
55

66
#include "ggml.h"
7-
#include "../ggml/src/ggml-impl.h"
87
#include "ggml-backend.h"
98

109
#include <cstdio>
1110
#include <cstring>
12-
#include <unordered_map>
1311
#include <utility>
1412
#include <vector>
1513

@@ -187,76 +185,6 @@ void cascade_force_moe_consumers(
187185
}
188186
}
189187

190-
// ---- Phase 2 Graph Deep-Copy ----
191-
192-
void phase2_graph_cache::release() {
193-
for (auto * t : persistent_tensors) delete t;
194-
persistent_tensors.clear();
195-
if (persistent_gf) { delete[] (char *)persistent_gf; persistent_gf = nullptr; }
196-
valid = false;
197-
}
198-
199-
void deep_copy_phase2_graph(
200-
phase2_graph_cache & cache,
201-
ggml_cgraph * src_gf)
202-
{
203-
cache.release();
204-
205-
int n_nodes = ggml_graph_n_nodes(src_gf);
206-
int n_leafs = ggml_graph_n_leafs(src_gf);
207-
int total_t = n_nodes + n_leafs;
208-
209-
std::unordered_map<const ggml_tensor *, ggml_tensor *> map;
210-
211-
auto dup_tensor = [&](const ggml_tensor * src) -> ggml_tensor * {
212-
auto * dst = new ggml_tensor(*src);
213-
for (int s = 0; s < GGML_MAX_SRC; s++) dst->src[s] = src->src[s];
214-
dst->view_src = src->view_src;
215-
map[src] = dst;
216-
cache.persistent_tensors.push_back(dst);
217-
return dst;
218-
};
219-
220-
for (int i = 0; i < n_leafs; i++) dup_tensor(ggml_graph_leaf(src_gf, i));
221-
for (int i = 0; i < n_nodes; i++) dup_tensor(ggml_graph_node(src_gf, i));
222-
223-
for (auto * dst : cache.persistent_tensors) {
224-
for (int s = 0; s < GGML_MAX_SRC; s++) {
225-
if (dst->src[s]) {
226-
auto it = map.find(dst->src[s]);
227-
if (it != map.end()) dst->src[s] = it->second;
228-
}
229-
}
230-
if (dst->view_src) {
231-
auto it = map.find(dst->view_src);
232-
if (it != map.end()) dst->view_src = it->second;
233-
}
234-
}
235-
236-
size_t graph_bytes = sizeof(ggml_cgraph) + (size_t)total_t * sizeof(ggml_tensor *) * 2;
237-
char * buf = new char[graph_bytes]();
238-
cache.persistent_gf = (ggml_cgraph *)buf;
239-
cache.persistent_gf->size = total_t;
240-
cache.persistent_gf->n_nodes = 0;
241-
cache.persistent_gf->n_leafs = 0;
242-
cache.persistent_gf->nodes = (ggml_tensor **)(buf + sizeof(ggml_cgraph));
243-
cache.persistent_gf->leafs = cache.persistent_gf->nodes + total_t;
244-
cache.persistent_gf->order = src_gf->order;
245-
cache.persistent_gf->uid = 0;
246-
247-
for (int i = 0; i < n_leafs; i++) {
248-
auto it = map.find(ggml_graph_leaf(src_gf, i));
249-
cache.persistent_gf->leafs[cache.persistent_gf->n_leafs++] = it->second;
250-
}
251-
for (int i = 0; i < n_nodes; i++) {
252-
auto it = map.find(ggml_graph_node(src_gf, i));
253-
cache.persistent_gf->nodes[cache.persistent_gf->n_nodes++] = it->second;
254-
}
255-
256-
cache.valid = true;
257-
fprintf(stderr, "deep_copy_phase2_graph: copied %d nodes + %d leafs\n", n_nodes, n_leafs);
258-
}
259-
260188
} // namespace moe
261189

262190
#endif // GGML_USE_CUDA

src/moe-hijacker.h

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
11
#pragma once
22

3-
// Graph scanning, cascade forcing, and deep-copy caching for MoE Phase 2.
3+
// Graph scanning and cascade forcing for MoE Phase 2.
44
// Operates on phase2_hijack structs via reference parameters.
55
// All functions are in namespace moe.
66

77
#ifdef GGML_USE_CUDA
88

99
#include <utility>
10-
#include <unordered_map>
11-
#include <vector>
1210

1311
#include "ggml-backend.h"
1412

1513
struct phase2_hijack;
1614
struct ggml_cgraph;
17-
struct ggml_tensor;
1815

1916
namespace moe {
2017

@@ -36,17 +33,11 @@ void cascade_force_moe_consumers(
3633

3734
struct phase2_graph_cache {
3835
bool valid = false;
39-
ggml_cgraph * persistent_gf = nullptr;
40-
std::vector<ggml_tensor *> persistent_tensors;
4136

4237
void capture() { valid = true; }
43-
void release();
38+
void release() { valid = false; }
4439
};
4540

46-
void deep_copy_phase2_graph(
47-
phase2_graph_cache & cache,
48-
ggml_cgraph * src_gf);
49-
5041
} // namespace moe
5142

5243
#endif // GGML_USE_CUDA

0 commit comments

Comments
 (0)