#!/usr/bin/env python3
"""剥掉 Youtu-LLM-A7B-Base 输出开头的 / 残留标记。
背景
----
这个模型是 base 模型(官方 README:仅推荐 raw text continuation,chat_template
只是附带)。它在 assistant 轮起始处会固定先吐 ``(token id 128014),
"关闭"模板预先打开的思考块,然后才写正文:
文本:<|Assistant|> <- 模板写的,在提示词里
光合作用是... <- 模型写的
视觉:<|vision_start|>...描述这张图片。 <- 提示词里没有 assistant 标记
这是一张... <- 模型仍会先吐 1~2 个
llama.cpp 的自动解析器(common/chat-diff-analyzer.cpp)识别不出这对标记,
于是 `` 原样留在 message.content 里。本脚本在输出侧把它剥掉。
用法
----
llama-cli ... | python3 strip_think.py
llama-mtmd-cli ... | python3 strip_think.py --from-first-think
--from-first-think
先跳到首个 / 标记处再剥。llama-mtmd-cli 会在日志里夹带
3 行 chat template 示例(不带时间戳前缀,grep 滤不掉),用这个模式可以
直接从正文开始输出。
也可作为库使用:from strip_think import strip_leading_think, clip_to_first_think
"""
from __future__ import annotations
import re
import sys
# 行首(允许前置空白)连续出现的思考标记
_LEADING = re.compile(r"^\s*(?:(?:?think>)\s*)+")
def strip_leading_think(text: str) -> str:
"""删除文本开头连续的 / 标记及其后空白。"""
return _LEADING.sub("", text, count=1)
def clip_to_first_think(text: str) -> str:
"""从首个 或 处开始截取(找不到则原样返回)。"""
hits = [i for i in (text.find(""), text.find("")) if i >= 0]
if not hits:
return text
return text[min(hits):]
def main() -> int:
text = sys.stdin.read()
if "--from-first-think" in sys.argv[1:]:
text = clip_to_first_think(text)
sys.stdout.write(strip_leading_think(text))
return 0
if __name__ == "__main__":
sys.exit(main())