@@ -1817,76 +1817,121 @@ 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- // 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 );
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+ }
18741867 }
18751868 }
1876- }
1877-
1878- // alloc_graph: Token 1 = full reserve+alloc; Token 2+ = galloc fast-path (no reserve_n)
1879- if (!ggml_backend_sched_alloc_graph (sched_phase2.get (), phase2_gf)) { ret = GGML_STATUS_ALLOC_FAILED ; return nullptr ; }
1880-
1881- // Track cache hit for server metrics
1882- if (do_cuda && phase2_cache.valid ) {
18831869 n_reused++;
1884- }
1885- if (!phase2_cache.valid ) {
1886- phase2_cache.capture ();
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+ }
1925+ }
1926+ }
1927+ moe::deep_copy_phase2_graph (phase2_cache, phase2_gf);
1928+ if (!phase2_cache.persistent_gf ) { ret = GGML_STATUS_FAILED ; return nullptr ; }
18871929 h2_hijack.captured = true ;
18881930 }
18891931
1932+ // alloc_graph: Token 1 = full reserve+alloc; Token 2+ = galloc fast-path
1933+ if (!ggml_backend_sched_alloc_graph (sched_phase2.get (), phase2_gf)) { ret = GGML_STATUS_ALLOC_FAILED ; return nullptr ; }
1934+
18901935 ggml_backend_t be = ggml_backend_sched_get_backend (sched_phase2.get (), 0 );
18911936 if (res->t_logits ) ggml_backend_sched_set_tensor_backend (sched_phase2.get (), res->t_logits , be);
18921937 if (res->t_embd ) ggml_backend_sched_set_tensor_backend (sched_phase2.get (), res->t_embd , be);
0 commit comments