批次跳号与拉丁混入治理: 编号批缺失段逐一直出兜底(每段全新引擎)、拼回整句要求段段齐全(有洞宁缺不残,MISS seg-hole)、targetLangOk对日/中目标加拉丁占比>33%拒绝(拦manque类欧洲语言漂移)
This commit is contained in:
parent
679b88bec3
commit
635a06e1c5
|
|
@ -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 }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue