Buckets:

krea-community/krea-2 / encoder.py
mrfakename's picture
download
raw
3 kB
from dataclasses import dataclass
import torch
from torch import Tensor
from transformers import (
AutoTokenizer,
Qwen2TokenizerFast,
Qwen3VLForConditionalGeneration,
)
@dataclass
class TextEncoderConfig:
model_id: str
max_length: int = 512
select_layers: tuple[int, ...] = (2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35)
class Qwen3VLConditioner(torch.nn.Module):
def __init__(
self,
version: str,
max_length: int = 512,
select_layers: tuple[int, ...] = (2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35),
):
super().__init__()
self.qwen = Qwen3VLForConditionalGeneration.from_pretrained(version)
self.tokenizer = AutoTokenizer.from_pretrained(version, max_length=max_length)
self.processor = Qwen2TokenizerFast.from_pretrained(
version, max_length=max_length
)
self.qwen = self.qwen.eval().requires_grad_(False)
self.max_length = max_length
self.select_layers = select_layers
self.prompt_template_encode_prefix = "<|im_start|>system\nDescribe the image by detailing the color, shape, size, texture, quantity, text, spatial relationships of the objects and background:<|im_end|>\n<|im_start|>user\n"
self.prompt_template_encode_suffix = "<|im_end|>\n<|im_start|>assistant\n"
self.prompt_template_encode_start_idx = 34
self.prompt_template_encode_suffix_start_idx = 5
def forward(self, text: list[str]) -> tuple[Tensor, Tensor]:
prefix_idx = self.prompt_template_encode_start_idx
text = [self.prompt_template_encode_prefix + item for item in text]
suffix_text = [self.prompt_template_encode_suffix] * len(text)
suffix_inputs = self.processor(text=suffix_text, return_tensors="pt").to(
self.qwen.device, non_blocking=True
)
suffix_ids, suffix_mask = (
suffix_inputs["input_ids"],
suffix_inputs["attention_mask"].bool(),
)
with torch.no_grad():
inputs = self.tokenizer(
text,
truncation=True,
return_length=False,
return_overflowing_tokens=False,
padding="max_length",
max_length=self.max_length
+ prefix_idx
- self.prompt_template_encode_suffix_start_idx,
return_tensors="pt",
).to(self.qwen.device, non_blocking=True)
input_ids = torch.cat([inputs["input_ids"], suffix_ids], dim=1)
mask = torch.cat([inputs["attention_mask"].bool(), suffix_mask], dim=1)
states = self.qwen(
input_ids=input_ids, attention_mask=mask, output_hidden_states=True
)
hiddens = torch.stack(
[states.hidden_states[i] for i in self.select_layers], dim=2
)
hiddens = hiddens[:, prefix_idx:]
mask = mask[:, prefix_idx:]
return hiddens, mask

Xet Storage Details

Size:
3 kB
·
Xet hash:
16dfaff8315099b17946defc0996408e8f77ccf42bfc75eb77357de5103c57b3

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.