Make Gemma 4 channel close markers channel aware

decode() rewrote every <channel|> into </think>, including the close of a
channel that is not the thought channel. Only close a thought channel that was
actually opened in the decoded text; other channel markers are left alone for
the caller to strip.
This commit is contained in:
bymyself
2026-08-11 17:45:13 -07:00
parent 87ae3d3869
commit f3cfb0866d
2 changed files with 50 additions and 2 deletions

View File

@@ -6,6 +6,7 @@ import numpy as np
from tokenizers import Tokenizer
from dataclasses import dataclass
import math
import re
from comfy import sd1_clip
import comfy.model_management
@@ -1401,9 +1402,11 @@ class Gemma4SDTokenizer(Gemma4_Tokenizer, sd1_clip.SDTokenizer):
def decode(self, token_ids, **kwargs):
text = super().decode(token_ids, skip_special_tokens=False)
# Translate thinking channel markers to standard <think>/</think> tags
# Translate thinking channel markers to standard <think>/</think> tags. Only a close
# that ends a thought channel becomes </think>; generation primed with another channel
# leaves its opening marker in the prompt, so its close is not reasoning.
text = re.sub(r"<\|channel>thought\n(.*?)<channel\|>", r"<think>\n\1</think>", text, flags=re.DOTALL)
text = text.replace("<|channel>thought\n", "<think>\n")
text = text.replace("<channel|>", "</think>")
# Strip remaining special tokens
text = text.replace("<turn|>", "").replace("<eos>", "").strip()
return text