Spaces:
Running on Zero
Running on Zero
AndrianBalanescu
feat(zerogpu): add Breeze TTS 2 experimental voice + remove image gen by policy
4a8de45 Download zerogpu/models/logits_process.py from abalanescu/flow2: direct link, hf CLI and curl.
- Browser
- Download file 2.88 kB
-
https://huggingface.co/spaces/abalanescu/flow2/resolve/main/zerogpu/models/logits_process.py
- Command line
-
hf download hf://spaces/abalanescu/flow2/zerogpu/models/logits_process.py
-
curl -L -o logits_process.py https://huggingface.co/spaces/abalanescu/flow2/resolve/main/zerogpu/models/logits_process.py
2.88 kB
| from __future__ import annotations | |
| import torch | |
| from transformers.generation.logits_process import LogitsProcessor | |
| def mask_invalid_codec_token_logits( | |
| scores: torch.Tensor, | |
| *, | |
| codebook_size: int, | |
| token_vocab_size: int, | |
| ) -> torch.Tensor: | |
| """Mask reserved model tokens that are not valid codec codebook entries.""" | |
| if codebook_size <= 0 or token_vocab_size < codebook_size: | |
| raise ValueError( | |
| f"Invalid codec token range: codebook_size={codebook_size}, " | |
| f"token_vocab_size={token_vocab_size}" | |
| ) | |
| if token_vocab_size > scores.shape[-1]: | |
| raise ValueError( | |
| f"token_vocab_size={token_vocab_size} exceeds logits size {scores.shape[-1]}" | |
| ) | |
| if codebook_size < token_vocab_size: | |
| scores[..., codebook_size:token_vocab_size] = float("-inf") | |
| return scores | |
| class GeneratedTokenRepetitionPenaltyLogitsProcessor(LogitsProcessor): | |
| """Apply HF-style repetition penalty only to generated, in-vocab tokens.""" | |
| def __init__(self, penalty: float) -> None: | |
| if penalty <= 0: | |
| raise ValueError("penalty must be > 0") | |
| self.penalty = float(penalty) | |
| def __call__( | |
| self, input_ids: torch.LongTensor, scores: torch.FloatTensor | |
| ) -> torch.FloatTensor: | |
| # Breeze starts generation with 2D text prompt IDs, then replaces them | |
| # with 3D generated codec frames after the first decoding step. | |
| if input_ids.ndim == 2: | |
| return scores | |
| if input_ids.ndim != 3: | |
| raise ValueError( | |
| f"Expected 2D prompt IDs or 3D codec frames, got {input_ids.ndim}D" | |
| ) | |
| generated_ids = input_ids[..., 0] | |
| if self.penalty == 1.0 or generated_ids.numel() == 0: | |
| return scores | |
| vocab_size = scores.shape[-1] | |
| valid = (generated_ids >= 0) & (generated_ids < vocab_size) | |
| if not torch.any(valid): | |
| return scores | |
| # Invalid IDs use token 0 as a temporary gather/scatter target. Restore | |
| # token 0 explicitly afterward so those placeholders cannot affect it. | |
| safe_ids = generated_ids.masked_fill(~valid, 0) | |
| selected_scores = torch.gather(scores, 1, safe_ids) | |
| penalized_scores = torch.where( | |
| selected_scores < 0, | |
| selected_scores * self.penalty, | |
| selected_scores / self.penalty, | |
| ) | |
| processed = scores.clone() | |
| processed.scatter_(1, safe_ids, penalized_scores) | |
| original_zero = scores[:, 0] | |
| penalized_zero = torch.where( | |
| original_zero < 0, | |
| original_zero * self.penalty, | |
| original_zero / self.penalty, | |
| ) | |
| generated_zero = (valid & (generated_ids == 0)).any(dim=1) | |
| processed[:, 0] = torch.where(generated_zero, penalized_zero, original_zero) | |
| return processed | |