批次跳号与拉丁混入治理: 编号批缺失段逐一直出兜底(每段全新引擎)、拼回整句要求段段齐全(有洞宁缺不残,MISS seg-hole)、targetLangOk对日/中目标加拉丁占比>33%拒绝(拦manque类欧洲语言漂移)

This commit is contained in:
liwenhao2 2026-09-15 10:57:01 +08:00
parent 679b88bec3
commit 635a06e1c5
1 changed files with 45 additions and 7 deletions

View File

@ -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<String, String>()
@ -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 }
}
}