MiniCPM5 相关代码整体摘除(用户拍板):useMinicpm5 开关+三派生常量删除(gemma4-e2b 固定);renderMinicpmPrompt 与 minicpm 模板分支删除;think 块剥除(MiniCPM专属防御)删除(<|channel>thought 通用防御保留);prompts.md 适用模型/家族列表/PC复现示例全部改E2B;历史注释保留于退役处

This commit is contained in:
liwenhao2 2026-09-16 13:58:34 +08:00
parent 531b558c72
commit a39a08ae1c
4 changed files with 14 additions and 31 deletions

View File

@ -2,7 +2,7 @@
> 适用模型:`google/gemma-4-E2B-it-qat-q4_0-gguf` 的 `gemma-4-E2B_q4_0-it.gguf` > 适用模型:`google/gemma-4-E2B-it-qat-q4_0-gguf` 的 `gemma-4-E2B_q4_0-it.gguf`
> (架构 gemma4。2026-09-16 由 MiniCPM5-2B 切回:E2B 为真机验证过的稳定引擎, > (架构 gemma4。2026-09-16 由 MiniCPM5-2B 切回:E2B 为真机验证过的稳定引擎,
> MiniCPM5 多次"空模板回显";模板分支全部保留在 LlmEngine 可回切) > MiniCPM5 多次"空模板回显")
> 本文件是唯一事实源:App 内 `SummarizePipeline.kt` 逐字引用这里的文本。改提示词先改本文件。 > 本文件是唯一事实源:App 内 `SummarizePipeline.kt` 逐字引用这里的文本。改提示词先改本文件。
> PC 调试方法见文末「用 PC llama.cpp 复现」。 > PC 调试方法见文末「用 PC llama.cpp 复现」。
@ -17,7 +17,7 @@
## 1. 聊天模板(以代码为准) ## 1. 聊天模板(以代码为准)
模板由 `LlmEngine.renderChatPrompt` 按模型家族渲染:gemma4(旧)/ gemma3 / minicpm(ChatML im_start/im_end + 空 think 前缀禁用思考)。MiniCPM5 的确切 token 序列与特殊 id 以 `renderMinicpmPrompt` 与 GGUF 内嵌模板为准;PC 调试直接加 --jinja 用内置模板即可。 模板由 `LlmEngine.renderChatPrompt` 按模型家族渲染:gemma4 / gemma3(2026-09-16 起 MiniCPM 分支已摘除)。PC 调试直接加 --jinja 用内置模板即可。
--- ---
@ -107,12 +107,12 @@ schema(键名禁止改动):
## 用 PC llama.cpp 复现(提示词调优用) ## 用 PC llama.cpp 复现(提示词调优用)
1. 取 llama.cpp master(gemma3 及更早架构均支持,App 的 `libsummarize-llm-jni.so` 无需重编)。 1. 取 llama.cpp master(gemma3 及更早架构均支持,App 的 `libsummarize-llm-jni.so` 无需重编)。
2. 模型:`MiniCPM5-2B-Q4_K_M.gguf`(openbmb/MiniCPM5-2B-GGUF,架构 llama)。 2. 模型:`gemma-4-E2B_q4_0-it.gguf`(google/gemma-4-E2B-it-qat-q4_0-gguf,架构 gemma4)。
3. 跑 P1 示例(替换 sys/user 两段;`--jinja` 走 GGUF 内置模板,与 App 的 3. 跑 P1 示例(替换 sys/user 两段;`--jinja` 走 GGUF 内置模板,与 App 的
`renderMinicpmPrompt`——ChatML + 预填空 `<think>` 块禁用思考——等价): `renderGemma4Prompt`(<|turn> 系标记)等价):
```bash ```bash
llama-cli -m MiniCPM5-2B-Q4_K_M.gguf -c 8192 -ctk q8_0 -ctv f16 --jinja \ llama-cli -m gemma-4-E2B_q4_0-it.gguf -c 8192 -ctk q8_0 -ctv f16 --jinja \
--temp 0 -n 900 \ --temp 0 -n 900 \
--sys "$(sed -n '/^### SYSTEM/,/^```$/p' prompts.md | sed '1,2d;$d')" \ --sys "$(sed -n '/^### SYSTEM/,/^```$/p' prompts.md | sed '1,2d;$d')" \
-p "$USER_PROMPT" -p "$USER_PROMPT"

View File

@ -75,23 +75,13 @@ class LlmEngine(
append("<start_of_turn>model\n") append("<start_of_turn>model\n")
} }
// ---- MiniCPM5(ChatML,生成 prompt 默认带 think 块)---- // MiniCPM5 模板分支 2026-09-16 随引擎退役摘除(三连空模板回显,
// GGUF 模板 enable_thinking=false 时的 generation prompt 为: // 用户拍板弃用;历史实现见 git history)
// <|im_start|>assistant\n<think>\n\n</think>\n\n
// 显式预填空 think → 模型直接输出正文,不浪费解码在思考上。
// EOG 为 <|im_end|>(llama.cpp 官方 GGUF,元数据已配)。
fun renderMinicpmPrompt(system: String, user: String): String =
buildString {
append("<|im_start|>system\n").append(system.trim()).append("<|im_end|>\n")
append("<|im_start|>user\n").append(user.trim()).append("<|im_end|>\n")
append("<|im_start|>assistant\n<think>\n\n</think>\n\n")
}
fun renderChatPrompt(system: String, user: String, fun renderChatPrompt(system: String, user: String,
template: String = "gemma4"): String = template: String = "gemma4"): String =
when (template) { when (template) {
"gemma3" -> renderGemma3Prompt(system, user) "gemma3" -> renderGemma3Prompt(system, user)
"minicpm" -> renderMinicpmPrompt(system, user)
else -> renderGemma4Prompt(system, user) else -> renderGemma4Prompt(system, user)
} }
} }

View File

@ -305,17 +305,12 @@ class MainActivity : AppCompatActivity() {
// 完全一致。摘要是独立世界:专用后台线程 + 独立 .so(llama.cpp), // 完全一致。摘要是独立世界:专用后台线程 + 独立 .so(llama.cpp),
// 不 import 任何 sherpa-onnx ASR native 对象。 // 不 import 任何 sherpa-onnx ASR native 对象。
private val summarizeEnabled = true private val summarizeEnabled = true
// 摘要模型一键开关:true=MiniCPM5-2B(新);false=回退已验证的 Gemma-4-E2B // 摘要/翻译兜底引擎:固定 Gemma-4-E2B(2026-09-16 用户拍板,休眠开关
// 2026-09-16 用户拍板切回 false:MiniCPM5 三连空模板回显(9/14 起), // 一并摘除)。历史:MiniCPM5-2B 三连空模板回显(9/14 起)被弃用,
// E2B 为 9/11 真机验证过的稳定引擎;摘要与翻译兜底同步受益 // 切换实现见 git history;E2B 为 9/11 真机验证过的稳定引擎
private val useMinicpm5 = false private val summarizeModelDirName = "gemma4-e2b"
private val summarizeModelDirName: String private val summarizeGgufName = "gemma-4-E2B_q4_0-it.gguf"
get() = if (useMinicpm5) "minicpm5-2b" else "gemma4-e2b" private val summarizeChatTemplate = "gemma4"
private val summarizeGgufName: String
get() = if (useMinicpm5) "MiniCPM5-2B-Q4_K_M.gguf"
else "gemma-4-E2B_q4_0-it.gguf"
private val summarizeChatTemplate: String
get() = if (useMinicpm5) "minicpm" else "gemma4"
private lateinit var summarizeButton: Button private lateinit var summarizeButton: Button
private lateinit var copyMinutesButton: Button private lateinit var copyMinutesButton: Button
private lateinit var minutesStatus: TextView private lateinit var minutesStatus: TextView
@ -2357,7 +2352,7 @@ class MainActivity : AppCompatActivity() {
} }
} }
// 升档兜底:1B 全链失败后,用摘要引擎(E2B/MiniCPM5,已随纪要常驻外部 // 升档兜底:1B 全链失败后,用 E2B 引擎(已随纪要常驻外部
// 目录)低温再译一次。临时引擎用完即 release(KV 污染协议);预算将尽 // 目录)低温再译一次。临时引擎用完即 release(KV 污染协议);预算将尽
// (剩不到 8s)不启用。产物过同样的 echo/drift 质检,宁缺毋滥。 // (剩不到 8s)不启用。产物过同样的 echo/drift 质检,宁缺毋滥。
private fun translateFallback( private fun translateFallback(

View File

@ -306,8 +306,6 @@ class SummarizePipeline(
s = s.replace( s = s.replace(
Regex("<\\|channel>thought.*?<channel\\|>", RegexOption.DOT_MATCHES_ALL), "" Regex("<\\|channel>thought.*?<channel\\|>", RegexOption.DOT_MATCHES_ALL), ""
) )
// MiniCPM5 兜底:万一 think 块未被预填空掉仍然冒出来,一并剥除
s = s.replace(Regex("<think>.*?</think>", RegexOption.DOT_MATCHES_ALL), "")
s = s.replace(Regex("\n{3,}"), "\n\n") s = s.replace(Regex("\n{3,}"), "\n\n")
return s.trim() return s.trim()
} }