AI大模型生成maxTokens 与上下文context
maxTokens 表示:本次生成最多允许模型输出多少个 token。
简单说:
maxTokens是"回答长度上限",不是模型一定会生成这么多,也不是输入长度。
1. token 是什么?
token 可以近似理解为模型内部处理文本的最小片段。
它不完全等于:
1 个 token ≠ 1 个汉字
1 个 token ≠ 1 个英文单词
大概可以粗略理解:
中文:1 个汉字可能接近 1 个 token,也可能多个字合成一个 token
英文:1 个单词可能是 1 个或多个 token
标点、换行、特殊标记也会占 token
例如:
你好,请介绍一下自己。
可能会被切成若干个 token。
2. maxTokens 决定什么?
它主要决定:
模型最多生成多长的回答
比如:
maxTokens = 64
表示最多生成 64 个 token。
maxTokens = 256
表示最多生成 256 个 token。
maxTokens = 512
表示最多生成 512 个 token。
3. maxTokens 不是一定生成这么多
注意,它是"最大值",不是"固定值"。
模型可能提前停止,比如遇到:
结束符
EOS token
<|im_end|>
停止条件
用户点击 stop
native 层中断
所以:
maxTokens = 256
实际可能只生成:
30 个 token
80 个 token
150 个 token
只要模型认为回答结束,就可能提前停。
4. maxTokens 越大,会带来什么影响?
优点
回答可以更长
能解释更完整
适合总结、写文章、长回答
缺点
生成耗时更长
手机发热更明显
耗电更多
UI等待更久
更容易跑题
更容易占满上下文窗口
尤其是 Android 端侧小模型,maxTokens 不建议一上来设太大。
5. maxTokens 和 nCtx 的关系
这个很关键。
加载模型时有:
nCtx = 1024
nCtx 表示上下文窗口大小,也就是:
输入 prompt token 数 + 输出 token 数 <= nCtx
也就是说:
prompt 已经用了 700 tokens
nCtx = 1024
那么理论上最多只能再生成大约:
1024 - 700 = 324 tokens
如果设置:
maxTokens = 512
也不一定能完整生成 512,因为上下文空间不够。
所以实际应该满足:
promptTokens + maxTokens < nCtx
最好还留一点余量:
promptTokens + maxTokens <= nCtx - 32
6. 举个例子
假设:
nCtx = 1024
maxTokens = 256
如果 prompt 很短:
用户:你是谁?
模型最多可以生成 256 token。
但如果 prompt 很长,比如保留了多轮上下文:
system + 历史10轮对话 + 当前问题
它本身可能已经占了 900 token。
这时再设置:
maxTokens = 256
就可能导致:
上下文不够
生成失败
回答被截断
llama_decode 报错
7. Android 端侧推荐值
Android 端侧推理
小模型,例如 Qwen2.5-0.5B
nCtx 可能是 1024 / 1536 / 2048
建议:
普通聊天
maxTokens = 128
或者:
maxTokens = 256
比较合适。
简短问答 / 客服助手
maxTokens = 64
或者:
maxTokens = 128
优点是响应快。
长回答 / 总结 / 写作
maxTokens = 384
或者:
maxTokens = 512
但端侧小模型要注意耗时和发热。
8. 推荐默认配置
如果当前是:
nCtx = 1024
建议:
maxTokens = 128
或者:
maxTokens = 256
如果改成:
nCtx = 2048
可以考虑:
maxTokens = 256
或者:
maxTokens = 384
不建议小模型默认:
maxTokens = 1024
因为端侧体验会明显变慢。
9. 和 temperature 的区别
它们控制的是不同东西:
temperature:控制回答随机性/创造性
maxTokens:控制回答最大长度
例如:
temperature = 0.7f
maxTokens = 256
含义是:
用中等随机性生成,最多输出 256 token
10. 实际产品里建议怎么做?
可以根据场景动态设置:
val maxTokens = when (scene) {
"simple_chat" -> 128
"normal_chat" -> 256
"summary" -> 384
"writing" -> 512
else -> 256
}
也可以根据设备性能分级:
val maxTokens = when {
isLowEndDevice() -> 128
isMidDevice() -> 256
else -> 384
}
11. 总结
maxTokens表示模型本次最多输出多少 token。它决定回答长度上限,也直接影响生成耗时、耗电、发热和上下文占用。值越大,回答可能越长,但端侧生成越慢;值越小,响应更快,但回答可能不完整。
对 Android 端侧 ,建议先用:
maxTokens = 128 ~ 256