utdawn commited on
Commit
f85a33b
·
verified ·
1 Parent(s): a37151b

Create tokenization_llada2.py

Browse files
Files changed (1) hide show
  1. tokenization_llada2.py +86 -0
tokenization_llada2.py ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import logging
3
+ from typing import Any, Iterator, Union
4
+ from transformers import PreTrainedTokenizerFast
5
+ from transformers.convert_slow_tokenizer import bytes_to_unicode
6
+
7
+ from .tool_declaration_ts import encode_tools_to_typescript_style
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+
12
+ def deep_sort_dict(obj: Any) -> Any:
13
+ """Deep sort dict keys recursively to ensure stable hashing and tokenization."""
14
+ if isinstance(obj, dict):
15
+ return {k: deep_sort_dict(v) for k, v in sorted(obj.items())}
16
+ if isinstance(obj, list):
17
+ return [deep_sort_dict(item) for item in obj]
18
+ return obj
19
+
20
+
21
+ class CustomFastTokenizer(PreTrainedTokenizerFast):
22
+
23
+ def __init__(self, *args, **kwargs):
24
+ super().__init__(*args, **kwargs)
25
+
26
+ # Byte-to-unicode mapping for downstream tasks requiring single-byte decoding
27
+ self.byte_encoder = bytes_to_unicode()
28
+ self.byte_decoder = {v: k for k, v in self.byte_encoder.items()}
29
+
30
+ @staticmethod
31
+ def _split_whitespaces_or_nonwhitespaces(
32
+ s: str, max_consecutive_slice_len: int
33
+ ) -> Iterator[str]:
34
+ current_slice_len = 0
35
+ current_slice_is_space = s[0].isspace() if len(s) > 0 else False
36
+ slice_start = 0
37
+
38
+ for i in range(len(s)):
39
+ is_now_space = s[i].isspace()
40
+ if current_slice_is_space ^ is_now_space:
41
+ current_slice_len = 1
42
+ current_slice_is_space = is_now_space
43
+ else:
44
+ current_slice_len += 1
45
+ if current_slice_len > max_consecutive_slice_len:
46
+ yield s[slice_start:i]
47
+ slice_start = i
48
+ current_slice_len = 1
49
+ yield s[slice_start:]
50
+
51
+ def encode(self, text: Union[str, Any], *args, **kwargs) -> list[int]:
52
+ if not isinstance(text, str) or args or kwargs:
53
+ return super().encode(text, *args, **kwargs)
54
+
55
+ # Chunking thresholds to prevent OOM on very long texts
56
+ MAX_ENCODE_CHARS = 400_000
57
+ MAX_NO_WHITESPACES_CHARS = 25_000
58
+
59
+ all_substrs = []
60
+ for i in range(0, len(text), MAX_ENCODE_CHARS):
61
+ chunk = text[i : i + MAX_ENCODE_CHARS]
62
+ all_substrs.extend(
63
+ self._split_whitespaces_or_nonwhitespaces(
64
+ chunk, MAX_NO_WHITESPACES_CHARS
65
+ )
66
+ )
67
+
68
+ t = []
69
+ for substr in all_substrs:
70
+ t.extend(super().encode(substr, add_special_tokens=False))
71
+
72
+ return t
73
+
74
+ def apply_chat_template(self, conversation, tools=None, **kwargs):
75
+ tools = deep_sort_dict(tools)
76
+
77
+ if tools:
78
+ try:
79
+ tools_ts_str = encode_tools_to_typescript_style(tools)
80
+ kwargs["tools_ts_str"] = tools_ts_str
81
+ except Exception as e:
82
+ logger.error(f"Failed to convert tools to TypeScript style: {e}")
83
+
84
+ return super().apply_chat_template(
85
+ conversation=conversation, tools=tools, **kwargs
86
+ )