From 635a06e1c50a9c212a766f6d90855eb46beb612e Mon Sep 17 00:00:00 2001 From: liwenhao2 Date: Tue, 15 Sep 2026 10:57:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=B9=E6=AC=A1=E8=B7=B3=E5=8F=B7=E4=B8=8E?= =?UTF-8?q?=E6=8B=89=E4=B8=81=E6=B7=B7=E5=85=A5=E6=B2=BB=E7=90=86:=20?= =?UTF-8?q?=E7=BC=96=E5=8F=B7=E6=89=B9=E7=BC=BA=E5=A4=B1=E6=AE=B5=E9=80=90?= =?UTF-8?q?=E4=B8=80=E7=9B=B4=E5=87=BA=E5=85=9C=E5=BA=95(=E6=AF=8F?= =?UTF-8?q?=E6=AE=B5=E5=85=A8=E6=96=B0=E5=BC=95=E6=93=8E)=E3=80=81?= =?UTF-8?q?=E6=8B=BC=E5=9B=9E=E6=95=B4=E5=8F=A5=E8=A6=81=E6=B1=82=E6=AE=B5?= =?UTF-8?q?=E6=AE=B5=E9=BD=90=E5=85=A8(=E6=9C=89=E6=B4=9E=E5=AE=81?= =?UTF-8?q?=E7=BC=BA=E4=B8=8D=E6=AE=8B,MISS=20seg-hole)=E3=80=81targetLang?= =?UTF-8?q?Ok=E5=AF=B9=E6=97=A5/=E4=B8=AD=E7=9B=AE=E6=A0=87=E5=8A=A0?= =?UTF-8?q?=E6=8B=89=E4=B8=81=E5=8D=A0=E6=AF=94>33%=E6=8B=92=E7=BB=9D(?= =?UTF-8?q?=E6=8B=A6manque=E7=B1=BB=E6=AC=A7=E6=B4=B2=E8=AF=AD=E8=A8=80?= =?UTF-8?q?=E6=BC=82=E7=A7=BB)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/k2fsa/sherpa/onnx/MainActivity.kt | 52 ++++++++++++++++--- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/k2fsa/sherpa/onnx/MainActivity.kt b/app/src/main/java/com/k2fsa/sherpa/onnx/MainActivity.kt index 5438739..639a1b7 100644 --- a/app/src/main/java/com/k2fsa/sherpa/onnx/MainActivity.kt +++ b/app/src/main/java/com/k2fsa/sherpa/onnx/MainActivity.kt @@ -2141,11 +2141,37 @@ class MainActivity : AppCompatActivity() { } catch (t: Throwable) { Log.w(TAG, "TRANSLATE batch failed: " + t.message); null } - val byIdx = extractNumberedPairs(out) ?: return null + val byIdx = extractNumberedPairs(out) segKeys.forEachIndexed { i, st -> - byIdx[(i + 1).toString()]?.takeIf { it.isNotBlank() } + byIdx?.get((i + 1).toString())?.takeIf { it.isNotBlank() } ?.let { got[st.first] = it } } + // 模型对编号批会"犯懒跳号"(只写最后一段等)→ 缺失段逐一直出 + // 兜底;每段重建引擎(nativeGenerate 不清 KV,复用必复读) + val missSegs = segKeys.filter { !got.containsKey(it.first) } + if (missSegs.isNotEmpty()) { + Log.i(TAG, "BATCH incomplete " + got.size + "/" + + segKeys.size + " -> per-seg fallback") + for (st in missSegs) { + translateEngine?.let { runCatching { it.release() } } + translateEngine = null + val e2 = ensureTranslateEngine() ?: break + val one = try { + e2.generate( + systemPrompt = "你是专业翻译。把给出的文本翻译成" + + targetName + "。只输出译文本身,不要解释。" + + langHint + "。", + userPrompt = st.second, + maxNewTokens = (st.second.length * 2 + 96) + .coerceAtMost(1200), + temperature = 0f, + ) + } catch (t: Throwable) { null } + one?.trim()?.lines()?.firstOrNull { it.isNotBlank() } + ?.trim()?.takeIf { it.isNotEmpty() } + ?.let { got[st.first] = it } + } + } if (got.isEmpty()) return null } val res = HashMap() @@ -2154,10 +2180,14 @@ class MainActivity : AppCompatActivity() { if (n == null) got[key]?.let { res[key] = it } else { val sb = StringBuilder() + var full = true for (i in 0 until n) { - got[key + "#s" + i]?.let { sb.append(it) } + val g = got[key + "#s" + i] + if (g == null) { full = false; break } + sb.append(g) } - if (sb.isNotEmpty()) res[key] = sb.toString() + if (full) res[key] = sb.toString() + else Log.i(TAG, "MISS key=" + key + " reason=seg-hole") } } return if (res.isEmpty()) null else res @@ -2214,9 +2244,17 @@ class MainActivity : AppCompatActivity() { private fun targetLangOk(tr: String): Boolean { if (tr.length < 12) return true return when (uiLanguage()) { - "ja" -> tr.count { it.code in 0x3040..0x30FF } * 25 >= tr.length - "zh" -> tr.none { it.code in 0x3040..0x30FF } && - tr.count { c -> tradOnlyChars.contains(c) } <= 1 + "ja" -> { + val latin = tr.count { it in 'a'..'z' || it in 'A'..'Z' } + tr.count { it.code in 0x3040..0x30FF } * 25 >= tr.length && + latin * 3 <= tr.length + } + "zh" -> { + val latin = tr.count { it in 'a'..'z' || it in 'A'..'Z' } + tr.none { it.code in 0x3040..0x30FF } && + tr.count { c -> tradOnlyChars.contains(c) } <= 1 && + latin * 3 <= tr.length + } else -> tr.none { it.code >= 0x2E80 } } }