Kavin commited on
Commit
4d2099e
Β·
verified Β·
1 Parent(s): 8fcb128

Upload embedder.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. embedder.py +79 -0
embedder.py ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List
2
+ from typing import Tuple
3
+
4
+ import numpy as np
5
+ import torch
6
+ from torch import nn
7
+ from transformers import AutoTokenizer, T5EncoderModel
8
+
9
+
10
+ class TextEmbedder(nn.Module):
11
+ """
12
+ Minimal wrapper around a *frozen* T5-base (or any seq-to-seq encoder).
13
+
14
+ ──────────── Usage ─────────────
15
+ >>> txt = TextEmbedder("google-t5/t5-base", max_len=128)
16
+ >>> ids, mask = txt.tokenize("some text")
17
+ >>> z_txt = txt.encode(torch.tensor(ids)[None, :],
18
+ torch.tensor(mask)[None, :])
19
+ """
20
+ def __init__(
21
+ self,
22
+ model_name: str = "google-t5/t5-base",
23
+ max_len: int = 128,
24
+ dtype: torch.dtype = torch.float16, # keeps weights β‰ˆ2Γ— smaller
25
+ ):
26
+ super(TextEmbedder, self).__init__()
27
+ self.tokenizer = AutoTokenizer.from_pretrained(model_name)
28
+ self.encoder = T5EncoderModel.from_pretrained(model_name).to(dtype=dtype)
29
+ self.encoder.eval()
30
+ for p in self.encoder.parameters(): # freeze
31
+ p.requires_grad = False
32
+
33
+ self.max_len = max_len
34
+
35
+ # ------------------------------------------------------------ tokenize
36
+ @torch.no_grad()
37
+ def tokenize(self, text: str | List[str]) -> Tuple[np.ndarray, np.ndarray]:
38
+ """
39
+ padded position are set to 0, and attention mask to 1.
40
+ For example, if max_len=5 and text="hellow world",
41
+ the tokenizer will return:
42
+ input_ids = [21820, 296, 0, 0, 0]
43
+ attention_mask = [1, 1, 0, 0, 0]
44
+
45
+ Returns (input_ids[int32], attn_mask[int8]) shaped (max_len,)
46
+ (If *text* is a list, shapes are (B,max_len).)
47
+ """
48
+ batch = self.tokenizer(
49
+ text,
50
+ padding="max_length",
51
+ truncation=True,
52
+ max_length=self.max_len,
53
+ return_attention_mask=True,
54
+ )
55
+ ids = np.asarray(batch["input_ids"], dtype=np.int32)
56
+ mask = np.asarray(batch["attention_mask"], dtype=np.int8)
57
+ return ids, mask
58
+
59
+ # ------------------------------------------------------------ encode
60
+ @torch.no_grad()
61
+ def encode(
62
+ self,
63
+ input_ids: torch.LongTensor, # (B,L)
64
+ attention_mask: torch.BoolTensor, # (B,L)
65
+ ) -> torch.Tensor: # (B,L,H)
66
+ """
67
+ Run the frozen encoder and return the sequence embeddings
68
+ (no pooling – do that in your SigLIP loss if you wish).
69
+ """
70
+ input_ids = input_ids
71
+ attention_mask = attention_mask
72
+
73
+ out = self.encoder(input_ids=input_ids,
74
+ attention_mask=attention_mask,
75
+ return_dict=True)
76
+ return out.last_hidden_state # (B,L,hidden)
77
+
78
+
79
+