翻译改直译模式(用户拍板):去掉同轮上下文(≤600字)——触发点不再拼装、两级引擎签名去掉 context、transCtxBlock 删除、重试丢上下文环节随之废除;原先疑虑的'长上下文诱发漂移'变量一并消除;指代/省略句质量代价已知情
This commit is contained in:
parent
5dc9fdaf74
commit
f77f90e1e9
|
|
@ -2136,15 +2136,8 @@ class MainActivity : AppCompatActivity() {
|
|||
Toast.LENGTH_LONG).show()
|
||||
return
|
||||
}
|
||||
// 同轮上下文:本行中该句之前的句子(最近 ≤600 字),仅帮助模型消解
|
||||
// 指代/省略,不进入译文
|
||||
val ctx = StringBuilder()
|
||||
for (prev in s.line?.sentences.orEmpty()) {
|
||||
if (prev === s) break
|
||||
if (prev.text.isNotBlank()) ctx.append(prev.text.trim()).append(' ')
|
||||
}
|
||||
var context = ctx.toString().trim()
|
||||
if (context.length > 600) context = context.takeLast(600)
|
||||
// 直译模式(2026-09-16 用户拍板):不带同轮上下文,逐句独立翻译。
|
||||
// 原先 600 字上下文曾被怀疑是漂移诱因;指代/省略句的质量代价已知情
|
||||
s.transPending = true
|
||||
s.line?.let { notifyLine(it) }
|
||||
transBusy = true
|
||||
|
|
@ -2154,7 +2147,7 @@ class MainActivity : AppCompatActivity() {
|
|||
// 让核:翻译线程永远低于录音/ASR 线程优先级(工程惯例同定稿线程)
|
||||
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND)
|
||||
translateHandler.removeCallbacks(unloadRunnable)
|
||||
val tr = translateOne(srcId, srcText, context)
|
||||
val tr = translateOne(srcId, srcText)
|
||||
transBusy = false
|
||||
uiHandler.post {
|
||||
s.transPending = false
|
||||
|
|
@ -2281,24 +2274,23 @@ class MainActivity : AppCompatActivity() {
|
|||
// 点击翻译总入口:1B 主链失败 → 升档兜底(摘要引擎,多语言能力强得多)。
|
||||
// 歌词体/文言中文("最贪富贵的潦倒一生…")超 1B 边界,温度重试无用,
|
||||
// 唯一解是换更大的模型再试一次。
|
||||
private fun translateOne(sid: Long, src: String, context: String): String? {
|
||||
private fun translateOne(sid: Long, src: String): String? {
|
||||
// 时间预算:录音中 45s、空闲 95s。超预算宁可失败(toast 可重试),
|
||||
// 也不让重试链长时间抢 ASR 的核(饥饿会引发第一遍字幕复读)。
|
||||
val deadline = SystemClock.elapsedRealtime() +
|
||||
if (isRecording) 45_000L else 95_000L
|
||||
translateOne1B(sid, src, context, deadline)?.let { return it }
|
||||
return translateFallback(sid, src, context, deadline)
|
||||
translateOne1B(sid, src, deadline)?.let { return it }
|
||||
return translateFallback(sid, src, deadline)
|
||||
}
|
||||
|
||||
private fun translateOne1B(
|
||||
sid: Long, src: String, context: String, deadline: Long,
|
||||
sid: Long, src: String, deadline: Long,
|
||||
): String? {
|
||||
var temp = 0f
|
||||
var genRetry = 0
|
||||
// 重试预算:录音中只允许 1 次(两次尝试≈30s),给兜底留出时间窗——
|
||||
// 现场:三次尝试 15s×3 吃满 45s 预算,兜底被 skipped=budget 拒之门外
|
||||
val maxGenRetry = if (isRecording) 1 else 2
|
||||
var ctx = context
|
||||
var lastRej = ""
|
||||
while (true) {
|
||||
if (SystemClock.elapsedRealtime() > deadline) {
|
||||
|
|
@ -2306,7 +2298,7 @@ class MainActivity : AppCompatActivity() {
|
|||
return null
|
||||
}
|
||||
val map = translateNumbered(
|
||||
listOf(Pair(sid.toString(), src)), temp, ctx)
|
||||
listOf(Pair(sid.toString(), src)), temp)
|
||||
val raw = map?.get(sid.toString())?.trim()
|
||||
val srcTag = " src=" + SummarizePipeline.detectLanguage(src) +
|
||||
":" + src.take(20).replace("\n", " ")
|
||||
|
|
@ -2334,7 +2326,6 @@ class MainActivity : AppCompatActivity() {
|
|||
" temp=$temp" + srcTag)
|
||||
if (genRetry >= maxGenRetry) return null
|
||||
genRetry++; temp = if (temp == 0f) 0.3f else 0.7f
|
||||
if (genRetry >= 2) ctx = ""
|
||||
}
|
||||
isEcho(src, tr, echoJaccardTh(src)) -> {
|
||||
val es = tr.replace("\n", " ")
|
||||
|
|
@ -2343,7 +2334,6 @@ class MainActivity : AppCompatActivity() {
|
|||
lastRej = es
|
||||
if (genRetry >= maxGenRetry) return null
|
||||
genRetry++; temp = if (temp == 0f) 0.3f else 0.7f
|
||||
if (genRetry >= 2) ctx = ""
|
||||
}
|
||||
!targetLangOk(tr) -> {
|
||||
val sample = tr.replace("\n", " ")
|
||||
|
|
@ -2369,7 +2359,7 @@ class MainActivity : AppCompatActivity() {
|
|||
// 目录)低温再译一次。临时引擎用完即 release(KV 污染协议);预算将尽
|
||||
// (剩不到 8s)不启用。产物过同样的 echo/drift 质检,宁缺毋滥。
|
||||
private fun translateFallback(
|
||||
sid: Long, src: String, context: String, deadline: Long,
|
||||
sid: Long, src: String, deadline: Long,
|
||||
): String? {
|
||||
if (SystemClock.elapsedRealtime() > deadline - 8_000) {
|
||||
Log.i(TAG, "TAP-FALLBACK sid=$sid skipped=budget")
|
||||
|
|
@ -2399,7 +2389,7 @@ class MainActivity : AppCompatActivity() {
|
|||
"禁止道歉或说明无法完成,翻不了就输出空字符串。" +
|
||||
"文学性表达按原文风格意译,保留重复与排比。" +
|
||||
transLangHint() + "。",
|
||||
userPrompt = transCtxBlock(context) + src,
|
||||
userPrompt = src,
|
||||
maxNewTokens = (src.length * 2 + 96).coerceAtMost(1200),
|
||||
temperature = 0.2f, repeatPenalty = 1.1f,
|
||||
)
|
||||
|
|
@ -2432,9 +2422,6 @@ class MainActivity : AppCompatActivity() {
|
|||
"zh" -> "译文必须是简体中文(不得用繁体字,不要输出日语或英语)"
|
||||
else -> "The translation must be English only (no CJK characters)"
|
||||
}
|
||||
private fun transCtxBlock(context: String): String =
|
||||
if (context.isBlank()) "" else
|
||||
"【参考上下文(不要翻译)】\n" + context + "\n\n【需要翻译的句子】\n"
|
||||
|
||||
// 容错提取 "编号":"译文" 对:顺序扫描,不要求 JSON 完整闭合——
|
||||
// 生成被 maxNewTokens 截断时,已完成的条目仍能救出
|
||||
|
|
@ -2489,16 +2476,14 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
// 一批 = 一个全新引擎(nativeGenerate 不清 KV 的 workaround)。
|
||||
// items: key(通常是 sid 字符串) × 原文;context: 可选的同轮参考上下文
|
||||
// (只帮助消解指代,不进译文);返回 key × 译文,失败 null。
|
||||
// items: key(通常是 sid 字符串) × 原文;返回 key × 译文,失败 null。
|
||||
// 直译模式(2026-09-16):不再携带同轮上下文
|
||||
private fun translateNumbered(
|
||||
items: List<Pair<String, String>>, temp: Float = 0f,
|
||||
context: String = "",
|
||||
): Map<String, String>? {
|
||||
if (items.isEmpty()) return emptyMap()
|
||||
val targetName = transTargetName()
|
||||
val langHint = transLangHint()
|
||||
val ctxBlock = transCtxBlock(context)
|
||||
translateEngine?.let { runCatching { it.release() } }
|
||||
translateEngine = null
|
||||
val engine = ensureTranslateEngine() ?: return null
|
||||
|
|
@ -2524,7 +2509,7 @@ class MainActivity : AppCompatActivity() {
|
|||
"禁止道歉或说明无法完成,翻不了就输出空字符串。" +
|
||||
"你只在中文、日本語、English 三种语言之间翻译;" +
|
||||
"输入不属于这三种语言时输出空字符串。" + langHint + "。"
|
||||
val usr1 = ctxBlock + segKeys[0].second
|
||||
val usr1 = segKeys[0].second
|
||||
// 白卷事故诊断(2026-09-16):空 raw= 的现场缺"模型看到了什么"
|
||||
// 这一环;转储两段长度与首尾,排除提示词层脏数据
|
||||
Log.i(TAG, "TRANSLATE prompt sys.len=" + sys1.length +
|
||||
|
|
@ -2564,7 +2549,7 @@ class MainActivity : AppCompatActivity() {
|
|||
"你只在中文、日本語、English 三种语言之间翻译;" +
|
||||
"段不属于这三种语言时其值输出空字符串。" +
|
||||
langHint + "。",
|
||||
userPrompt = ctxBlock + "【文本】\n" + numbered,
|
||||
userPrompt = "【文本】\n" + numbered,
|
||||
maxNewTokens = budget, temperature = temp,
|
||||
repeatPenalty = 1.1f,
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue