Repository: li-plus/chatglm.cpp (language: python)

Issue:
MACOS部署响应时间较长，出字速度还行
非专业提问，请谅解。

运行设备：MACMINI M2

使用mps加速，在提问的时候，有较长的响应时间，期间CPU单核100%，这个过程时间很长，尤其是在有多条上下文的时候较为明显。到了输出的时候，CPU下降，GPU满载，这个时候的速度就很美了。

简单说就是出字速度快，但是前边的响应时间很长，是特性或者有优化的方法？


下面是我使用的命令：
git clone --recursive https://github.com/li-plus/chatglm.cpp.git && cd chatglm.cpp
python convert.py -i /Users/admin/chatglm2-6b -t q4_0 -o chatglm2-ggml.bin
cmake -B build -DGGML_METAL=ON && cmake --build build -j
CMAKE_ARGS="-DGGML_METAL=ON" pip install 'chatglm-cpp[api]'
MODEL=../chatglm2-ggml.bin uvicorn chatglm_cpp.openai_api:app --host 0.0.0.0 --port 8000


Discussion / hints:
上游llama.cpp已经修复了这个问题，等待同步到本仓库就好
同问

Fix patch:
diff --git a/chatglm.cpp b/chatglm.cpp
index 17de1b3..0b4d6ac 100644
--- a/chatglm.cpp
+++ b/chatglm.cpp
@@ -458,11 +458,7 @@ int BaseModelForConditionalGeneration::generate_next_token(const std::vector<int
 
     ggml_build_forward_expand(&ctx_.gf, lm_logits);
 #ifdef GGML_USE_METAL
-    if (input_ids.size() == 1) {
-        ggml_metal_graph_compute(ctx_.ctx_metal.get(), &ctx_.gf);
-    } else {
-        ggml_graph_compute_helper(ctx_.work_buffer, &ctx_.gf, n_threads);
-    }
+    ggml_metal_graph_compute(ctx_.ctx_metal.get(), &ctx_.gf);
 #else
     ggml_graph_compute_helper(ctx_.work_buffer, &ctx_.gf, n_threads);
 #endif
@@ -1190,6 +1186,11 @@ ggml_tensor *GLM2MLP::forward(ModelContext *ctx, ggml_tensor *hidden_states) con
 #ifdef GGML_USE_CUBLAS
     x0 = ggml_cont(gctx, x0);
     tensor_assign_buffers(x0);
+#elif defined(GGML_USE_METAL)
+    if (x0->ne[1] > 1) {
+        x0 = ggml_cont(gctx, x0);
+        tensor_assign_buffers(x0);
+    }
 #endif
     x0 = ggml_silu_inplace(gctx, x0);
     tensor_assign_buffers(x0);
@@ -1199,6 +1200,11 @@ ggml_tensor *GLM2MLP::forward(ModelContext *ctx, ggml_tensor *hidden_states) con
 #ifdef GGML_USE_CUBLAS
     x1 = ggml_cont(gctx, x1);
     tensor_assign_buffers(x1);
+#elif defined(GGML_USE_METAL)
+    if (x1->ne[1] > 1) {
+        x1 = ggml_cont(gctx, x1);
+        tensor_assign_buffers(x1);
+    }
 #endif
 
     output = ggml_mul_inplace(gctx, x0, x1);
diff --git a/third_party/ggml b/third_party/ggml
index 244776a..6319ae9 160000
--- a/third_party/ggml
+++ b/third_party/ggml
@@ -1,1 +1,1 @@
-Subproject commit 244776a089ebed7f0332f9c8bdc38d2d40464493
+Subproject commit 6319ae9ad7bdf9f834b2855d7e9fa70508e82f57


Test patch:
diff --git a/chatglm_test.cpp b/chatglm_test.cpp
index 0c397be..26bfe78 100644
--- a/chatglm_test.cpp
+++ b/chatglm_test.cpp
@@ -680,7 +680,7 @@ TEST_F(ChatGLMTest, GLM2Block) {
         EXPECT_EQ(out_y1->backend, x1->backend);
         out_y1->backend = GGML_BACKEND_CPU;
         ggml_build_forward_expand(&ctx.gf, out_y1);
-        cpu_graph_compute(get_num_threads());
+        device_graph_compute(get_num_threads());
 
         expect_all_close(ref_y1, out_y1, eps);
     }
@@ -759,7 +759,7 @@ TEST_F(ChatGLMTest, BenchmarkGLM2Block) {
             ggml_tensor *self_attn_y = model.forward(&ctx, self_attn_x, 0);
             ggml_build_forward_expand(&ctx.gf, self_attn_y);
             std::cout << "[Benchmark] GLM2Block " << ggml_type_name(dtype)
-                      << " self attn time: " << perf_cpu_graph_compute() << " ms\n";
+                      << " self attn time: " << perf_device_graph_compute() << " ms\n";
         }
 
         // cross attention