@@ -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)
0 commit comments