Transformers
tobiges commited on
Commit
265c09f
·
verified ·
1 Parent(s): 0dbb91e

Upload processor

Browse files
processing_action_tokenizer.py CHANGED
@@ -1,8 +1,9 @@
1
  import logging
2
- from typing import ClassVar, Iterator
3
 
4
  import numpy as np
5
- from scipy.fft import dct, idct
 
6
  from tokenizers import ByteLevelBPETokenizer
7
  from tokenizers.trainers import BpeTrainer
8
  from transformers import PreTrainedTokenizerFast
@@ -40,9 +41,7 @@ class UniversalActionProcessor(ProcessorMixin):
40
  super().__init__(bpe_tokenizer)
41
 
42
  def __call__(self, action_chunk: np.array) -> np.array:
43
- assert action_chunk.ndim <= 3, (
44
- "Only 3 dimensions supported: [batch, timesteps, action_dim]"
45
- )
46
  if action_chunk.ndim == 2:
47
  action_chunk = action_chunk[None, ...]
48
 
@@ -54,9 +53,7 @@ class UniversalActionProcessor(ProcessorMixin):
54
  dct_coeff = np.around(dct_coeff * self.scale)
55
  tokens = []
56
  for elem in dct_coeff:
57
- token_str = "".join(
58
- map(chr, np.maximum(elem.flatten() - self.min_token, 0).astype(int))
59
- )
60
  tokens.append(self.bpe_tokenizer(token_str)["input_ids"])
61
  return tokens
62
 
@@ -67,46 +64,41 @@ class UniversalActionProcessor(ProcessorMixin):
67
  time_horizon: int | None = None,
68
  action_dim: int | None = None,
69
  ) -> np.array:
70
- self.time_horizon = (
71
- time_horizon or self.time_horizon or self.called_time_horizon
72
- )
73
  self.action_dim = action_dim or self.action_dim or self.called_action_dim
74
 
75
  # Cache the time horizon and action dimension for the next call
76
  self.called_time_horizon = self.time_horizon
77
  self.called_action_dim = self.action_dim
78
 
79
- assert self.time_horizon is not None and self.action_dim is not None, (
80
- "Tokenizer not initialized, call encode() once or pass in time_horizon and action_dim."
81
- )
82
 
83
  decoded_actions = []
84
  for token in tokens:
85
  try:
86
  decoded_tokens = self.bpe_tokenizer.decode(token)
87
- decoded_dct_coeff = (
88
- np.array(list(map(ord, decoded_tokens))) + self.min_token
89
- )
90
  decoded_dct_coeff = decoded_dct_coeff.reshape(-1, self.action_dim)
91
- assert decoded_dct_coeff.shape == (
92
- self.time_horizon,
93
- self.action_dim,
94
- ), (
95
- f"Decoded DCT coefficients have shape {decoded_dct_coeff.shape}, expected ({self.time_horizon}, {self.action_dim})"
96
- )
 
97
  except Exception as e:
98
  print(f"Error decoding tokens: {e}")
99
  print(f"Tokens: {token}")
100
  decoded_dct_coeff = np.zeros((self.time_horizon, self.action_dim))
101
- decoded_actions.append(
102
- idct(decoded_dct_coeff / self.scale, axis=0, norm="ortho")
103
- )
104
  return np.stack(decoded_actions)
105
 
106
  @classmethod
107
  def fit(
108
  cls,
109
- action_data: Iterator[np.array],
110
  scale: float = 10,
111
  vocab_size: int = 1024,
112
  *,
@@ -114,27 +106,16 @@ class UniversalActionProcessor(ProcessorMixin):
114
  action_dim: int | None = None,
115
  ) -> "UniversalActionProcessor":
116
  # Run DCT over all inputs
117
- print("Running DCT over all inputs")
118
-
119
- def _convert_dct(tokens: np.array) -> np.array:
120
- tokens = dct(tokens, axis=0, norm="ortho").flatten()
121
- tokens = np.around(tokens * scale)
122
- return tokens
123
- dct_tokens = [_convert_dct(a) for a in action_data]
124
- # dct_tokens = [dct(a, axis=0, norm="ortho").flatten() for a in action_data]
125
- # # dct_tokens_rounded = np.around(np.concatenate(dct_tokens) * scale)
126
- # dct_tokens_rounded = [np.around(tokens * scale) for tokens in dct_tokens]
127
- print("Converted actions to DCT tokens")
128
 
129
  # Quantize and find min token
130
- max_token = int(max([tokens.max() for tokens in dct_tokens]))
131
- min_token = int(min([tokens.min() for tokens in dct_tokens]))
132
  min_vocab_size = max_token - min_token
133
- print("Found min and max tokens: ", min_token, max_token)
134
 
135
- assert min_vocab_size <= vocab_size, (
136
- f"Vocab size {vocab_size} is too small for the range of tokens {min_vocab_size}"
137
- )
138
  if min_vocab_size + 100 > vocab_size:
139
  logging.warning(
140
  f"Initial alphabet size {min_vocab_size} is almost as large as the vocab"
@@ -142,17 +123,16 @@ class UniversalActionProcessor(ProcessorMixin):
142
  )
143
 
144
  # Make token iterator for BPE training
145
- comp_tokens = []
146
- while dct_tokens:
147
- tokens = dct_tokens.pop()
148
- rounded_tokens = tokens - min_token
149
- rounded_tokens = rounded_tokens.astype(int)
150
- string = "".join(map(chr, rounded_tokens))
151
- comp_tokens.append(string)
152
- print("Stringified DCT tokens")
153
 
154
  # Train BPE tokenizer
155
  bpe = ByteLevelBPETokenizer()
 
156
  # Set up the entire range of possible tokens as the initial alphabet
157
  alphabet = [chr(i) for i in range(max_token - min_token + 1)]
158
  trainer = BpeTrainer(
@@ -163,21 +143,13 @@ class UniversalActionProcessor(ProcessorMixin):
163
  initial_alphabet=alphabet,
164
  max_token_length=10000,
165
  )
166
- print("Started training BPE tokenizer")
167
-
168
- def _token_iter():
169
- while comp_tokens:
170
- yield comp_tokens.pop()
171
 
172
  # Train the inner tokenizer (don't use ByteLevelBPETokenizer.train_from_iterator()
173
  # because it doesn't support custom alphabets)
174
- bpe._tokenizer.train_from_iterator(_token_iter(), trainer=trainer, length=len(dct_tokens))
175
- print("Trained BPE tokenizer")
176
 
177
  return cls(
178
- PreTrainedTokenizerFast(
179
- tokenizer_object=bpe, clean_up_tokenization_spaces=False
180
- ),
181
  scale=scale,
182
  vocab_size=vocab_size,
183
  min_token=min_token,
 
1
  import logging
2
+ from typing import ClassVar
3
 
4
  import numpy as np
5
+ from scipy.fft import dct
6
+ from scipy.fft import idct
7
  from tokenizers import ByteLevelBPETokenizer
8
  from tokenizers.trainers import BpeTrainer
9
  from transformers import PreTrainedTokenizerFast
 
41
  super().__init__(bpe_tokenizer)
42
 
43
  def __call__(self, action_chunk: np.array) -> np.array:
44
+ assert action_chunk.ndim <= 3, "Only 3 dimensions supported: [batch, timesteps, action_dim]"
 
 
45
  if action_chunk.ndim == 2:
46
  action_chunk = action_chunk[None, ...]
47
 
 
53
  dct_coeff = np.around(dct_coeff * self.scale)
54
  tokens = []
55
  for elem in dct_coeff:
56
+ token_str = "".join(map(chr, np.maximum(elem.flatten() - self.min_token, 0).astype(int)))
 
 
57
  tokens.append(self.bpe_tokenizer(token_str)["input_ids"])
58
  return tokens
59
 
 
64
  time_horizon: int | None = None,
65
  action_dim: int | None = None,
66
  ) -> np.array:
67
+ self.time_horizon = time_horizon or self.time_horizon or self.called_time_horizon
 
 
68
  self.action_dim = action_dim or self.action_dim or self.called_action_dim
69
 
70
  # Cache the time horizon and action dimension for the next call
71
  self.called_time_horizon = self.time_horizon
72
  self.called_action_dim = self.action_dim
73
 
74
+ assert (
75
+ self.time_horizon is not None and self.action_dim is not None
76
+ ), "Tokenizer not initialized, call encode() once or pass in time_horizon and action_dim."
77
 
78
  decoded_actions = []
79
  for token in tokens:
80
  try:
81
  decoded_tokens = self.bpe_tokenizer.decode(token)
82
+ decoded_dct_coeff = np.array(list(map(ord, decoded_tokens))) + self.min_token
 
 
83
  decoded_dct_coeff = decoded_dct_coeff.reshape(-1, self.action_dim)
84
+ assert (
85
+ decoded_dct_coeff.shape
86
+ == (
87
+ self.time_horizon,
88
+ self.action_dim,
89
+ )
90
+ ), f"Decoded DCT coefficients have shape {decoded_dct_coeff.shape}, expected ({self.time_horizon}, {self.action_dim})"
91
  except Exception as e:
92
  print(f"Error decoding tokens: {e}")
93
  print(f"Tokens: {token}")
94
  decoded_dct_coeff = np.zeros((self.time_horizon, self.action_dim))
95
+ decoded_actions.append(idct(decoded_dct_coeff / self.scale, axis=0, norm="ortho"))
 
 
96
  return np.stack(decoded_actions)
97
 
98
  @classmethod
99
  def fit(
100
  cls,
101
+ action_data: list[np.array],
102
  scale: float = 10,
103
  vocab_size: int = 1024,
104
  *,
 
106
  action_dim: int | None = None,
107
  ) -> "UniversalActionProcessor":
108
  # Run DCT over all inputs
109
+ dct_tokens = [dct(a, axis=0, norm="ortho").flatten() for a in action_data]
 
 
 
 
 
 
 
 
 
 
110
 
111
  # Quantize and find min token
112
+ max_token = int(np.around(np.concatenate(dct_tokens) * scale).max())
113
+ min_token = int(np.around(np.concatenate(dct_tokens) * scale).min())
114
  min_vocab_size = max_token - min_token
 
115
 
116
+ assert (
117
+ min_vocab_size <= vocab_size
118
+ ), f"Vocab size {vocab_size} is too small for the range of tokens {min_vocab_size}"
119
  if min_vocab_size + 100 > vocab_size:
120
  logging.warning(
121
  f"Initial alphabet size {min_vocab_size} is almost as large as the vocab"
 
123
  )
124
 
125
  # Make token iterator for BPE training
126
+ def _token_iter():
127
+ for tokens in dct_tokens:
128
+ rounded_tokens = np.around(tokens * scale) - min_token
129
+ rounded_tokens = rounded_tokens.astype(int)
130
+ string = "".join(map(chr, rounded_tokens))
131
+ yield string
 
 
132
 
133
  # Train BPE tokenizer
134
  bpe = ByteLevelBPETokenizer()
135
+
136
  # Set up the entire range of possible tokens as the initial alphabet
137
  alphabet = [chr(i) for i in range(max_token - min_token + 1)]
138
  trainer = BpeTrainer(
 
143
  initial_alphabet=alphabet,
144
  max_token_length=10000,
145
  )
 
 
 
 
 
146
 
147
  # Train the inner tokenizer (don't use ByteLevelBPETokenizer.train_from_iterator()
148
  # because it doesn't support custom alphabets)
149
+ bpe._tokenizer.train_from_iterator(_token_iter(), trainer=trainer)
 
150
 
151
  return cls(
152
+ PreTrainedTokenizerFast(tokenizer_object=bpe, clean_up_tokenization_spaces=False),
 
 
153
  scale=scale,
154
  vocab_size=vocab_size,
155
  min_token=min_token,
processor_config.json CHANGED
@@ -3,7 +3,7 @@
3
  "auto_map": {
4
  "AutoProcessor": "processing_action_tokenizer.UniversalActionProcessor"
5
  },
6
- "min_token": -27,
7
  "processor_class": "UniversalActionProcessor",
8
  "scale": 10,
9
  "time_horizon": null,
 
3
  "auto_map": {
4
  "AutoProcessor": "processing_action_tokenizer.UniversalActionProcessor"
5
  },
6
+ "min_token": -519,
7
  "processor_class": "UniversalActionProcessor",
8
  "scale": 10,
9
  "time_horizon": null,
tokenizer.json CHANGED
The diff for this file is too large to render. See raw diff