JinghuiLuAstronaut commited on
Commit
af3e74f
·
verified ·
1 Parent(s): b6aa186

Add files using upload-large-folder tool

Browse files
Files changed (20) hide show
  1. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35/lib/python3.12/site-packages/pip/_internal/models/__init__.py +2 -0
  2. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35/lib/python3.12/site-packages/pip/_internal/models/direct_url.py +235 -0
  3. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35/lib/python3.12/site-packages/pip/_internal/models/format_control.py +78 -0
  4. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35/lib/python3.12/site-packages/pip/_internal/models/installation_report.py +56 -0
  5. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35/lib/python3.12/site-packages/pip/_internal/models/link.py +579 -0
  6. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35/lib/python3.12/site-packages/pip/_internal/models/search_scope.py +132 -0
  7. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35/lib/python3.12/site-packages/pip/_internal/models/selection_prefs.py +51 -0
  8. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35/lib/python3.12/site-packages/pip/_internal/models/wheel.py +92 -0
  9. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/m2m_100/__init__.py +28 -0
  10. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/m2m_100/configuration_m2m_100.py +75 -0
  11. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/m2m_100/modeling_m2m_100.py +923 -0
  12. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/m2m_100/tokenization_m2m_100.py +384 -0
  13. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/nanochat/__init__.py +14 -0
  14. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/nanochat/configuration_nanochat.py +81 -0
  15. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/nanochat/modeling_nanochat.py +518 -0
  16. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/nanochat/modular_nanochat.py +235 -0
  17. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/qwen3_5_moe/__init__.py +27 -0
  18. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/qwen3_5_moe/configuration_qwen3_5_moe.py +197 -0
  19. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/qwen3_5_moe/modeling_qwen3_5_moe.py +0 -0
  20. LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/t5gemma2/configuration_t5gemma2.py +403 -0
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35/lib/python3.12/site-packages/pip/_internal/models/__init__.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ """A package that contains models that represent entities.
2
+ """
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35/lib/python3.12/site-packages/pip/_internal/models/direct_url.py ADDED
@@ -0,0 +1,235 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """ PEP 610 """
2
+ import json
3
+ import re
4
+ import urllib.parse
5
+ from typing import Any, Dict, Iterable, Optional, Type, TypeVar, Union
6
+
7
+ __all__ = [
8
+ "DirectUrl",
9
+ "DirectUrlValidationError",
10
+ "DirInfo",
11
+ "ArchiveInfo",
12
+ "VcsInfo",
13
+ ]
14
+
15
+ T = TypeVar("T")
16
+
17
+ DIRECT_URL_METADATA_NAME = "direct_url.json"
18
+ ENV_VAR_RE = re.compile(r"^\$\{[A-Za-z0-9-_]+\}(:\$\{[A-Za-z0-9-_]+\})?$")
19
+
20
+
21
+ class DirectUrlValidationError(Exception):
22
+ pass
23
+
24
+
25
+ def _get(
26
+ d: Dict[str, Any], expected_type: Type[T], key: str, default: Optional[T] = None
27
+ ) -> Optional[T]:
28
+ """Get value from dictionary and verify expected type."""
29
+ if key not in d:
30
+ return default
31
+ value = d[key]
32
+ if not isinstance(value, expected_type):
33
+ raise DirectUrlValidationError(
34
+ f"{value!r} has unexpected type for {key} (expected {expected_type})"
35
+ )
36
+ return value
37
+
38
+
39
+ def _get_required(
40
+ d: Dict[str, Any], expected_type: Type[T], key: str, default: Optional[T] = None
41
+ ) -> T:
42
+ value = _get(d, expected_type, key, default)
43
+ if value is None:
44
+ raise DirectUrlValidationError(f"{key} must have a value")
45
+ return value
46
+
47
+
48
+ def _exactly_one_of(infos: Iterable[Optional["InfoType"]]) -> "InfoType":
49
+ infos = [info for info in infos if info is not None]
50
+ if not infos:
51
+ raise DirectUrlValidationError(
52
+ "missing one of archive_info, dir_info, vcs_info"
53
+ )
54
+ if len(infos) > 1:
55
+ raise DirectUrlValidationError(
56
+ "more than one of archive_info, dir_info, vcs_info"
57
+ )
58
+ assert infos[0] is not None
59
+ return infos[0]
60
+
61
+
62
+ def _filter_none(**kwargs: Any) -> Dict[str, Any]:
63
+ """Make dict excluding None values."""
64
+ return {k: v for k, v in kwargs.items() if v is not None}
65
+
66
+
67
+ class VcsInfo:
68
+ name = "vcs_info"
69
+
70
+ def __init__(
71
+ self,
72
+ vcs: str,
73
+ commit_id: str,
74
+ requested_revision: Optional[str] = None,
75
+ ) -> None:
76
+ self.vcs = vcs
77
+ self.requested_revision = requested_revision
78
+ self.commit_id = commit_id
79
+
80
+ @classmethod
81
+ def _from_dict(cls, d: Optional[Dict[str, Any]]) -> Optional["VcsInfo"]:
82
+ if d is None:
83
+ return None
84
+ return cls(
85
+ vcs=_get_required(d, str, "vcs"),
86
+ commit_id=_get_required(d, str, "commit_id"),
87
+ requested_revision=_get(d, str, "requested_revision"),
88
+ )
89
+
90
+ def _to_dict(self) -> Dict[str, Any]:
91
+ return _filter_none(
92
+ vcs=self.vcs,
93
+ requested_revision=self.requested_revision,
94
+ commit_id=self.commit_id,
95
+ )
96
+
97
+
98
+ class ArchiveInfo:
99
+ name = "archive_info"
100
+
101
+ def __init__(
102
+ self,
103
+ hash: Optional[str] = None,
104
+ hashes: Optional[Dict[str, str]] = None,
105
+ ) -> None:
106
+ # set hashes before hash, since the hash setter will further populate hashes
107
+ self.hashes = hashes
108
+ self.hash = hash
109
+
110
+ @property
111
+ def hash(self) -> Optional[str]:
112
+ return self._hash
113
+
114
+ @hash.setter
115
+ def hash(self, value: Optional[str]) -> None:
116
+ if value is not None:
117
+ # Auto-populate the hashes key to upgrade to the new format automatically.
118
+ # We don't back-populate the legacy hash key from hashes.
119
+ try:
120
+ hash_name, hash_value = value.split("=", 1)
121
+ except ValueError:
122
+ raise DirectUrlValidationError(
123
+ f"invalid archive_info.hash format: {value!r}"
124
+ )
125
+ if self.hashes is None:
126
+ self.hashes = {hash_name: hash_value}
127
+ elif hash_name not in self.hashes:
128
+ self.hashes = self.hashes.copy()
129
+ self.hashes[hash_name] = hash_value
130
+ self._hash = value
131
+
132
+ @classmethod
133
+ def _from_dict(cls, d: Optional[Dict[str, Any]]) -> Optional["ArchiveInfo"]:
134
+ if d is None:
135
+ return None
136
+ return cls(hash=_get(d, str, "hash"), hashes=_get(d, dict, "hashes"))
137
+
138
+ def _to_dict(self) -> Dict[str, Any]:
139
+ return _filter_none(hash=self.hash, hashes=self.hashes)
140
+
141
+
142
+ class DirInfo:
143
+ name = "dir_info"
144
+
145
+ def __init__(
146
+ self,
147
+ editable: bool = False,
148
+ ) -> None:
149
+ self.editable = editable
150
+
151
+ @classmethod
152
+ def _from_dict(cls, d: Optional[Dict[str, Any]]) -> Optional["DirInfo"]:
153
+ if d is None:
154
+ return None
155
+ return cls(editable=_get_required(d, bool, "editable", default=False))
156
+
157
+ def _to_dict(self) -> Dict[str, Any]:
158
+ return _filter_none(editable=self.editable or None)
159
+
160
+
161
+ InfoType = Union[ArchiveInfo, DirInfo, VcsInfo]
162
+
163
+
164
+ class DirectUrl:
165
+ def __init__(
166
+ self,
167
+ url: str,
168
+ info: InfoType,
169
+ subdirectory: Optional[str] = None,
170
+ ) -> None:
171
+ self.url = url
172
+ self.info = info
173
+ self.subdirectory = subdirectory
174
+
175
+ def _remove_auth_from_netloc(self, netloc: str) -> str:
176
+ if "@" not in netloc:
177
+ return netloc
178
+ user_pass, netloc_no_user_pass = netloc.split("@", 1)
179
+ if (
180
+ isinstance(self.info, VcsInfo)
181
+ and self.info.vcs == "git"
182
+ and user_pass == "git"
183
+ ):
184
+ return netloc
185
+ if ENV_VAR_RE.match(user_pass):
186
+ return netloc
187
+ return netloc_no_user_pass
188
+
189
+ @property
190
+ def redacted_url(self) -> str:
191
+ """url with user:password part removed unless it is formed with
192
+ environment variables as specified in PEP 610, or it is ``git``
193
+ in the case of a git URL.
194
+ """
195
+ purl = urllib.parse.urlsplit(self.url)
196
+ netloc = self._remove_auth_from_netloc(purl.netloc)
197
+ surl = urllib.parse.urlunsplit(
198
+ (purl.scheme, netloc, purl.path, purl.query, purl.fragment)
199
+ )
200
+ return surl
201
+
202
+ def validate(self) -> None:
203
+ self.from_dict(self.to_dict())
204
+
205
+ @classmethod
206
+ def from_dict(cls, d: Dict[str, Any]) -> "DirectUrl":
207
+ return DirectUrl(
208
+ url=_get_required(d, str, "url"),
209
+ subdirectory=_get(d, str, "subdirectory"),
210
+ info=_exactly_one_of(
211
+ [
212
+ ArchiveInfo._from_dict(_get(d, dict, "archive_info")),
213
+ DirInfo._from_dict(_get(d, dict, "dir_info")),
214
+ VcsInfo._from_dict(_get(d, dict, "vcs_info")),
215
+ ]
216
+ ),
217
+ )
218
+
219
+ def to_dict(self) -> Dict[str, Any]:
220
+ res = _filter_none(
221
+ url=self.redacted_url,
222
+ subdirectory=self.subdirectory,
223
+ )
224
+ res[self.info.name] = self.info._to_dict()
225
+ return res
226
+
227
+ @classmethod
228
+ def from_json(cls, s: str) -> "DirectUrl":
229
+ return cls.from_dict(json.loads(s))
230
+
231
+ def to_json(self) -> str:
232
+ return json.dumps(self.to_dict(), sort_keys=True)
233
+
234
+ def is_local_editable(self) -> bool:
235
+ return isinstance(self.info, DirInfo) and self.info.editable
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35/lib/python3.12/site-packages/pip/_internal/models/format_control.py ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import FrozenSet, Optional, Set
2
+
3
+ from pip._vendor.packaging.utils import canonicalize_name
4
+
5
+ from pip._internal.exceptions import CommandError
6
+
7
+
8
+ class FormatControl:
9
+ """Helper for managing formats from which a package can be installed."""
10
+
11
+ __slots__ = ["no_binary", "only_binary"]
12
+
13
+ def __init__(
14
+ self,
15
+ no_binary: Optional[Set[str]] = None,
16
+ only_binary: Optional[Set[str]] = None,
17
+ ) -> None:
18
+ if no_binary is None:
19
+ no_binary = set()
20
+ if only_binary is None:
21
+ only_binary = set()
22
+
23
+ self.no_binary = no_binary
24
+ self.only_binary = only_binary
25
+
26
+ def __eq__(self, other: object) -> bool:
27
+ if not isinstance(other, self.__class__):
28
+ return NotImplemented
29
+
30
+ if self.__slots__ != other.__slots__:
31
+ return False
32
+
33
+ return all(getattr(self, k) == getattr(other, k) for k in self.__slots__)
34
+
35
+ def __repr__(self) -> str:
36
+ return f"{self.__class__.__name__}({self.no_binary}, {self.only_binary})"
37
+
38
+ @staticmethod
39
+ def handle_mutual_excludes(value: str, target: Set[str], other: Set[str]) -> None:
40
+ if value.startswith("-"):
41
+ raise CommandError(
42
+ "--no-binary / --only-binary option requires 1 argument."
43
+ )
44
+ new = value.split(",")
45
+ while ":all:" in new:
46
+ other.clear()
47
+ target.clear()
48
+ target.add(":all:")
49
+ del new[: new.index(":all:") + 1]
50
+ # Without a none, we want to discard everything as :all: covers it
51
+ if ":none:" not in new:
52
+ return
53
+ for name in new:
54
+ if name == ":none:":
55
+ target.clear()
56
+ continue
57
+ name = canonicalize_name(name)
58
+ other.discard(name)
59
+ target.add(name)
60
+
61
+ def get_allowed_formats(self, canonical_name: str) -> FrozenSet[str]:
62
+ result = {"binary", "source"}
63
+ if canonical_name in self.only_binary:
64
+ result.discard("source")
65
+ elif canonical_name in self.no_binary:
66
+ result.discard("binary")
67
+ elif ":all:" in self.only_binary:
68
+ result.discard("source")
69
+ elif ":all:" in self.no_binary:
70
+ result.discard("binary")
71
+ return frozenset(result)
72
+
73
+ def disallow_binaries(self) -> None:
74
+ self.handle_mutual_excludes(
75
+ ":all:",
76
+ self.no_binary,
77
+ self.only_binary,
78
+ )
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35/lib/python3.12/site-packages/pip/_internal/models/installation_report.py ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, Dict, Sequence
2
+
3
+ from pip._vendor.packaging.markers import default_environment
4
+
5
+ from pip import __version__
6
+ from pip._internal.req.req_install import InstallRequirement
7
+
8
+
9
+ class InstallationReport:
10
+ def __init__(self, install_requirements: Sequence[InstallRequirement]):
11
+ self._install_requirements = install_requirements
12
+
13
+ @classmethod
14
+ def _install_req_to_dict(cls, ireq: InstallRequirement) -> Dict[str, Any]:
15
+ assert ireq.download_info, f"No download_info for {ireq}"
16
+ res = {
17
+ # PEP 610 json for the download URL. download_info.archive_info.hashes may
18
+ # be absent when the requirement was installed from the wheel cache
19
+ # and the cache entry was populated by an older pip version that did not
20
+ # record origin.json.
21
+ "download_info": ireq.download_info.to_dict(),
22
+ # is_direct is true if the requirement was a direct URL reference (which
23
+ # includes editable requirements), and false if the requirement was
24
+ # downloaded from a PEP 503 index or --find-links.
25
+ "is_direct": ireq.is_direct,
26
+ # is_yanked is true if the requirement was yanked from the index, but
27
+ # was still selected by pip to conform to PEP 592.
28
+ "is_yanked": ireq.link.is_yanked if ireq.link else False,
29
+ # requested is true if the requirement was specified by the user (aka
30
+ # top level requirement), and false if it was installed as a dependency of a
31
+ # requirement. https://peps.python.org/pep-0376/#requested
32
+ "requested": ireq.user_supplied,
33
+ # PEP 566 json encoding for metadata
34
+ # https://www.python.org/dev/peps/pep-0566/#json-compatible-metadata
35
+ "metadata": ireq.get_dist().metadata_dict,
36
+ }
37
+ if ireq.user_supplied and ireq.extras:
38
+ # For top level requirements, the list of requested extras, if any.
39
+ res["requested_extras"] = sorted(ireq.extras)
40
+ return res
41
+
42
+ def to_dict(self) -> Dict[str, Any]:
43
+ return {
44
+ "version": "1",
45
+ "pip_version": __version__,
46
+ "install": [
47
+ self._install_req_to_dict(ireq) for ireq in self._install_requirements
48
+ ],
49
+ # https://peps.python.org/pep-0508/#environment-markers
50
+ # TODO: currently, the resolver uses the default environment to evaluate
51
+ # environment markers, so that is what we report here. In the future, it
52
+ # should also take into account options such as --python-version or
53
+ # --platform, perhaps under the form of an environment_override field?
54
+ # https://github.com/pypa/pip/issues/11198
55
+ "environment": default_environment(),
56
+ }
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35/lib/python3.12/site-packages/pip/_internal/models/link.py ADDED
@@ -0,0 +1,579 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import functools
2
+ import itertools
3
+ import logging
4
+ import os
5
+ import posixpath
6
+ import re
7
+ import urllib.parse
8
+ from dataclasses import dataclass
9
+ from typing import (
10
+ TYPE_CHECKING,
11
+ Any,
12
+ Dict,
13
+ List,
14
+ Mapping,
15
+ NamedTuple,
16
+ Optional,
17
+ Tuple,
18
+ Union,
19
+ )
20
+
21
+ from pip._internal.utils.deprecation import deprecated
22
+ from pip._internal.utils.filetypes import WHEEL_EXTENSION
23
+ from pip._internal.utils.hashes import Hashes
24
+ from pip._internal.utils.misc import (
25
+ pairwise,
26
+ redact_auth_from_url,
27
+ split_auth_from_netloc,
28
+ splitext,
29
+ )
30
+ from pip._internal.utils.models import KeyBasedCompareMixin
31
+ from pip._internal.utils.urls import path_to_url, url_to_path
32
+
33
+ if TYPE_CHECKING:
34
+ from pip._internal.index.collector import IndexContent
35
+
36
+ logger = logging.getLogger(__name__)
37
+
38
+
39
+ # Order matters, earlier hashes have a precedence over later hashes for what
40
+ # we will pick to use.
41
+ _SUPPORTED_HASHES = ("sha512", "sha384", "sha256", "sha224", "sha1", "md5")
42
+
43
+
44
+ @dataclass(frozen=True)
45
+ class LinkHash:
46
+ """Links to content may have embedded hash values. This class parses those.
47
+
48
+ `name` must be any member of `_SUPPORTED_HASHES`.
49
+
50
+ This class can be converted to and from `ArchiveInfo`. While ArchiveInfo intends to
51
+ be JSON-serializable to conform to PEP 610, this class contains the logic for
52
+ parsing a hash name and value for correctness, and then checking whether that hash
53
+ conforms to a schema with `.is_hash_allowed()`."""
54
+
55
+ name: str
56
+ value: str
57
+
58
+ _hash_url_fragment_re = re.compile(
59
+ # NB: we do not validate that the second group (.*) is a valid hex
60
+ # digest. Instead, we simply keep that string in this class, and then check it
61
+ # against Hashes when hash-checking is needed. This is easier to debug than
62
+ # proactively discarding an invalid hex digest, as we handle incorrect hashes
63
+ # and malformed hashes in the same place.
64
+ r"[#&]({choices})=([^&]*)".format(
65
+ choices="|".join(re.escape(hash_name) for hash_name in _SUPPORTED_HASHES)
66
+ ),
67
+ )
68
+
69
+ def __post_init__(self) -> None:
70
+ assert self.name in _SUPPORTED_HASHES
71
+
72
+ @classmethod
73
+ @functools.lru_cache(maxsize=None)
74
+ def find_hash_url_fragment(cls, url: str) -> Optional["LinkHash"]:
75
+ """Search a string for a checksum algorithm name and encoded output value."""
76
+ match = cls._hash_url_fragment_re.search(url)
77
+ if match is None:
78
+ return None
79
+ name, value = match.groups()
80
+ return cls(name=name, value=value)
81
+
82
+ def as_dict(self) -> Dict[str, str]:
83
+ return {self.name: self.value}
84
+
85
+ def as_hashes(self) -> Hashes:
86
+ """Return a Hashes instance which checks only for the current hash."""
87
+ return Hashes({self.name: [self.value]})
88
+
89
+ def is_hash_allowed(self, hashes: Optional[Hashes]) -> bool:
90
+ """
91
+ Return True if the current hash is allowed by `hashes`.
92
+ """
93
+ if hashes is None:
94
+ return False
95
+ return hashes.is_hash_allowed(self.name, hex_digest=self.value)
96
+
97
+
98
+ @dataclass(frozen=True)
99
+ class MetadataFile:
100
+ """Information about a core metadata file associated with a distribution."""
101
+
102
+ hashes: Optional[Dict[str, str]]
103
+
104
+ def __post_init__(self) -> None:
105
+ if self.hashes is not None:
106
+ assert all(name in _SUPPORTED_HASHES for name in self.hashes)
107
+
108
+
109
+ def supported_hashes(hashes: Optional[Dict[str, str]]) -> Optional[Dict[str, str]]:
110
+ # Remove any unsupported hash types from the mapping. If this leaves no
111
+ # supported hashes, return None
112
+ if hashes is None:
113
+ return None
114
+ hashes = {n: v for n, v in hashes.items() if n in _SUPPORTED_HASHES}
115
+ if not hashes:
116
+ return None
117
+ return hashes
118
+
119
+
120
+ def _clean_url_path_part(part: str) -> str:
121
+ """
122
+ Clean a "part" of a URL path (i.e. after splitting on "@" characters).
123
+ """
124
+ # We unquote prior to quoting to make sure nothing is double quoted.
125
+ return urllib.parse.quote(urllib.parse.unquote(part))
126
+
127
+
128
+ def _clean_file_url_path(part: str) -> str:
129
+ """
130
+ Clean the first part of a URL path that corresponds to a local
131
+ filesystem path (i.e. the first part after splitting on "@" characters).
132
+ """
133
+ # We unquote prior to quoting to make sure nothing is double quoted.
134
+ # Also, on Windows the path part might contain a drive letter which
135
+ # should not be quoted. On Linux where drive letters do not
136
+ # exist, the colon should be quoted. We rely on urllib.request
137
+ # to do the right thing here.
138
+ return urllib.request.pathname2url(urllib.request.url2pathname(part))
139
+
140
+
141
+ # percent-encoded: /
142
+ _reserved_chars_re = re.compile("(@|%2F)", re.IGNORECASE)
143
+
144
+
145
+ def _clean_url_path(path: str, is_local_path: bool) -> str:
146
+ """
147
+ Clean the path portion of a URL.
148
+ """
149
+ if is_local_path:
150
+ clean_func = _clean_file_url_path
151
+ else:
152
+ clean_func = _clean_url_path_part
153
+
154
+ # Split on the reserved characters prior to cleaning so that
155
+ # revision strings in VCS URLs are properly preserved.
156
+ parts = _reserved_chars_re.split(path)
157
+
158
+ cleaned_parts = []
159
+ for to_clean, reserved in pairwise(itertools.chain(parts, [""])):
160
+ cleaned_parts.append(clean_func(to_clean))
161
+ # Normalize %xx escapes (e.g. %2f -> %2F)
162
+ cleaned_parts.append(reserved.upper())
163
+
164
+ return "".join(cleaned_parts)
165
+
166
+
167
+ def _ensure_quoted_url(url: str) -> str:
168
+ """
169
+ Make sure a link is fully quoted.
170
+ For example, if ' ' occurs in the URL, it will be replaced with "%20",
171
+ and without double-quoting other characters.
172
+ """
173
+ # Split the URL into parts according to the general structure
174
+ # `scheme://netloc/path;parameters?query#fragment`.
175
+ result = urllib.parse.urlparse(url)
176
+ # If the netloc is empty, then the URL refers to a local filesystem path.
177
+ is_local_path = not result.netloc
178
+ path = _clean_url_path(result.path, is_local_path=is_local_path)
179
+ return urllib.parse.urlunparse(result._replace(path=path))
180
+
181
+
182
+ class Link(KeyBasedCompareMixin):
183
+ """Represents a parsed link from a Package Index's simple URL"""
184
+
185
+ __slots__ = [
186
+ "_parsed_url",
187
+ "_url",
188
+ "_hashes",
189
+ "comes_from",
190
+ "requires_python",
191
+ "yanked_reason",
192
+ "metadata_file_data",
193
+ "cache_link_parsing",
194
+ "egg_fragment",
195
+ ]
196
+
197
+ def __init__(
198
+ self,
199
+ url: str,
200
+ comes_from: Optional[Union[str, "IndexContent"]] = None,
201
+ requires_python: Optional[str] = None,
202
+ yanked_reason: Optional[str] = None,
203
+ metadata_file_data: Optional[MetadataFile] = None,
204
+ cache_link_parsing: bool = True,
205
+ hashes: Optional[Mapping[str, str]] = None,
206
+ ) -> None:
207
+ """
208
+ :param url: url of the resource pointed to (href of the link)
209
+ :param comes_from: instance of IndexContent where the link was found,
210
+ or string.
211
+ :param requires_python: String containing the `Requires-Python`
212
+ metadata field, specified in PEP 345. This may be specified by
213
+ a data-requires-python attribute in the HTML link tag, as
214
+ described in PEP 503.
215
+ :param yanked_reason: the reason the file has been yanked, if the
216
+ file has been yanked, or None if the file hasn't been yanked.
217
+ This is the value of the "data-yanked" attribute, if present, in
218
+ a simple repository HTML link. If the file has been yanked but
219
+ no reason was provided, this should be the empty string. See
220
+ PEP 592 for more information and the specification.
221
+ :param metadata_file_data: the metadata attached to the file, or None if
222
+ no such metadata is provided. This argument, if not None, indicates
223
+ that a separate metadata file exists, and also optionally supplies
224
+ hashes for that file.
225
+ :param cache_link_parsing: A flag that is used elsewhere to determine
226
+ whether resources retrieved from this link should be cached. PyPI
227
+ URLs should generally have this set to False, for example.
228
+ :param hashes: A mapping of hash names to digests to allow us to
229
+ determine the validity of a download.
230
+ """
231
+
232
+ # The comes_from, requires_python, and metadata_file_data arguments are
233
+ # only used by classmethods of this class, and are not used in client
234
+ # code directly.
235
+
236
+ # url can be a UNC windows share
237
+ if url.startswith("\\\\"):
238
+ url = path_to_url(url)
239
+
240
+ self._parsed_url = urllib.parse.urlsplit(url)
241
+ # Store the url as a private attribute to prevent accidentally
242
+ # trying to set a new value.
243
+ self._url = url
244
+
245
+ link_hash = LinkHash.find_hash_url_fragment(url)
246
+ hashes_from_link = {} if link_hash is None else link_hash.as_dict()
247
+ if hashes is None:
248
+ self._hashes = hashes_from_link
249
+ else:
250
+ self._hashes = {**hashes, **hashes_from_link}
251
+
252
+ self.comes_from = comes_from
253
+ self.requires_python = requires_python if requires_python else None
254
+ self.yanked_reason = yanked_reason
255
+ self.metadata_file_data = metadata_file_data
256
+
257
+ super().__init__(key=url, defining_class=Link)
258
+
259
+ self.cache_link_parsing = cache_link_parsing
260
+ self.egg_fragment = self._egg_fragment()
261
+
262
+ @classmethod
263
+ def from_json(
264
+ cls,
265
+ file_data: Dict[str, Any],
266
+ page_url: str,
267
+ ) -> Optional["Link"]:
268
+ """
269
+ Convert an pypi json document from a simple repository page into a Link.
270
+ """
271
+ file_url = file_data.get("url")
272
+ if file_url is None:
273
+ return None
274
+
275
+ url = _ensure_quoted_url(urllib.parse.urljoin(page_url, file_url))
276
+ pyrequire = file_data.get("requires-python")
277
+ yanked_reason = file_data.get("yanked")
278
+ hashes = file_data.get("hashes", {})
279
+
280
+ # PEP 714: Indexes must use the name core-metadata, but
281
+ # clients should support the old name as a fallback for compatibility.
282
+ metadata_info = file_data.get("core-metadata")
283
+ if metadata_info is None:
284
+ metadata_info = file_data.get("dist-info-metadata")
285
+
286
+ # The metadata info value may be a boolean, or a dict of hashes.
287
+ if isinstance(metadata_info, dict):
288
+ # The file exists, and hashes have been supplied
289
+ metadata_file_data = MetadataFile(supported_hashes(metadata_info))
290
+ elif metadata_info:
291
+ # The file exists, but there are no hashes
292
+ metadata_file_data = MetadataFile(None)
293
+ else:
294
+ # False or not present: the file does not exist
295
+ metadata_file_data = None
296
+
297
+ # The Link.yanked_reason expects an empty string instead of a boolean.
298
+ if yanked_reason and not isinstance(yanked_reason, str):
299
+ yanked_reason = ""
300
+ # The Link.yanked_reason expects None instead of False.
301
+ elif not yanked_reason:
302
+ yanked_reason = None
303
+
304
+ return cls(
305
+ url,
306
+ comes_from=page_url,
307
+ requires_python=pyrequire,
308
+ yanked_reason=yanked_reason,
309
+ hashes=hashes,
310
+ metadata_file_data=metadata_file_data,
311
+ )
312
+
313
+ @classmethod
314
+ def from_element(
315
+ cls,
316
+ anchor_attribs: Dict[str, Optional[str]],
317
+ page_url: str,
318
+ base_url: str,
319
+ ) -> Optional["Link"]:
320
+ """
321
+ Convert an anchor element's attributes in a simple repository page to a Link.
322
+ """
323
+ href = anchor_attribs.get("href")
324
+ if not href:
325
+ return None
326
+
327
+ url = _ensure_quoted_url(urllib.parse.urljoin(base_url, href))
328
+ pyrequire = anchor_attribs.get("data-requires-python")
329
+ yanked_reason = anchor_attribs.get("data-yanked")
330
+
331
+ # PEP 714: Indexes must use the name data-core-metadata, but
332
+ # clients should support the old name as a fallback for compatibility.
333
+ metadata_info = anchor_attribs.get("data-core-metadata")
334
+ if metadata_info is None:
335
+ metadata_info = anchor_attribs.get("data-dist-info-metadata")
336
+ # The metadata info value may be the string "true", or a string of
337
+ # the form "hashname=hashval"
338
+ if metadata_info == "true":
339
+ # The file exists, but there are no hashes
340
+ metadata_file_data = MetadataFile(None)
341
+ elif metadata_info is None:
342
+ # The file does not exist
343
+ metadata_file_data = None
344
+ else:
345
+ # The file exists, and hashes have been supplied
346
+ hashname, sep, hashval = metadata_info.partition("=")
347
+ if sep == "=":
348
+ metadata_file_data = MetadataFile(supported_hashes({hashname: hashval}))
349
+ else:
350
+ # Error - data is wrong. Treat as no hashes supplied.
351
+ logger.debug(
352
+ "Index returned invalid data-dist-info-metadata value: %s",
353
+ metadata_info,
354
+ )
355
+ metadata_file_data = MetadataFile(None)
356
+
357
+ return cls(
358
+ url,
359
+ comes_from=page_url,
360
+ requires_python=pyrequire,
361
+ yanked_reason=yanked_reason,
362
+ metadata_file_data=metadata_file_data,
363
+ )
364
+
365
+ def __str__(self) -> str:
366
+ if self.requires_python:
367
+ rp = f" (requires-python:{self.requires_python})"
368
+ else:
369
+ rp = ""
370
+ if self.comes_from:
371
+ return f"{redact_auth_from_url(self._url)} (from {self.comes_from}){rp}"
372
+ else:
373
+ return redact_auth_from_url(str(self._url))
374
+
375
+ def __repr__(self) -> str:
376
+ return f"<Link {self}>"
377
+
378
+ @property
379
+ def url(self) -> str:
380
+ return self._url
381
+
382
+ @property
383
+ def filename(self) -> str:
384
+ path = self.path.rstrip("/")
385
+ name = posixpath.basename(path)
386
+ if not name:
387
+ # Make sure we don't leak auth information if the netloc
388
+ # includes a username and password.
389
+ netloc, user_pass = split_auth_from_netloc(self.netloc)
390
+ return netloc
391
+
392
+ name = urllib.parse.unquote(name)
393
+ assert name, f"URL {self._url!r} produced no filename"
394
+ return name
395
+
396
+ @property
397
+ def file_path(self) -> str:
398
+ return url_to_path(self.url)
399
+
400
+ @property
401
+ def scheme(self) -> str:
402
+ return self._parsed_url.scheme
403
+
404
+ @property
405
+ def netloc(self) -> str:
406
+ """
407
+ This can contain auth information.
408
+ """
409
+ return self._parsed_url.netloc
410
+
411
+ @property
412
+ def path(self) -> str:
413
+ return urllib.parse.unquote(self._parsed_url.path)
414
+
415
+ def splitext(self) -> Tuple[str, str]:
416
+ return splitext(posixpath.basename(self.path.rstrip("/")))
417
+
418
+ @property
419
+ def ext(self) -> str:
420
+ return self.splitext()[1]
421
+
422
+ @property
423
+ def url_without_fragment(self) -> str:
424
+ scheme, netloc, path, query, fragment = self._parsed_url
425
+ return urllib.parse.urlunsplit((scheme, netloc, path, query, ""))
426
+
427
+ _egg_fragment_re = re.compile(r"[#&]egg=([^&]*)")
428
+
429
+ # Per PEP 508.
430
+ _project_name_re = re.compile(
431
+ r"^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$", re.IGNORECASE
432
+ )
433
+
434
+ def _egg_fragment(self) -> Optional[str]:
435
+ match = self._egg_fragment_re.search(self._url)
436
+ if not match:
437
+ return None
438
+
439
+ # An egg fragment looks like a PEP 508 project name, along with
440
+ # an optional extras specifier. Anything else is invalid.
441
+ project_name = match.group(1)
442
+ if not self._project_name_re.match(project_name):
443
+ deprecated(
444
+ reason=f"{self} contains an egg fragment with a non-PEP 508 name",
445
+ replacement="to use the req @ url syntax, and remove the egg fragment",
446
+ gone_in="25.0",
447
+ issue=11617,
448
+ )
449
+
450
+ return project_name
451
+
452
+ _subdirectory_fragment_re = re.compile(r"[#&]subdirectory=([^&]*)")
453
+
454
+ @property
455
+ def subdirectory_fragment(self) -> Optional[str]:
456
+ match = self._subdirectory_fragment_re.search(self._url)
457
+ if not match:
458
+ return None
459
+ return match.group(1)
460
+
461
+ def metadata_link(self) -> Optional["Link"]:
462
+ """Return a link to the associated core metadata file (if any)."""
463
+ if self.metadata_file_data is None:
464
+ return None
465
+ metadata_url = f"{self.url_without_fragment}.metadata"
466
+ if self.metadata_file_data.hashes is None:
467
+ return Link(metadata_url)
468
+ return Link(metadata_url, hashes=self.metadata_file_data.hashes)
469
+
470
+ def as_hashes(self) -> Hashes:
471
+ return Hashes({k: [v] for k, v in self._hashes.items()})
472
+
473
+ @property
474
+ def hash(self) -> Optional[str]:
475
+ return next(iter(self._hashes.values()), None)
476
+
477
+ @property
478
+ def hash_name(self) -> Optional[str]:
479
+ return next(iter(self._hashes), None)
480
+
481
+ @property
482
+ def show_url(self) -> str:
483
+ return posixpath.basename(self._url.split("#", 1)[0].split("?", 1)[0])
484
+
485
+ @property
486
+ def is_file(self) -> bool:
487
+ return self.scheme == "file"
488
+
489
+ def is_existing_dir(self) -> bool:
490
+ return self.is_file and os.path.isdir(self.file_path)
491
+
492
+ @property
493
+ def is_wheel(self) -> bool:
494
+ return self.ext == WHEEL_EXTENSION
495
+
496
+ @property
497
+ def is_vcs(self) -> bool:
498
+ from pip._internal.vcs import vcs
499
+
500
+ return self.scheme in vcs.all_schemes
501
+
502
+ @property
503
+ def is_yanked(self) -> bool:
504
+ return self.yanked_reason is not None
505
+
506
+ @property
507
+ def has_hash(self) -> bool:
508
+ return bool(self._hashes)
509
+
510
+ def is_hash_allowed(self, hashes: Optional[Hashes]) -> bool:
511
+ """
512
+ Return True if the link has a hash and it is allowed by `hashes`.
513
+ """
514
+ if hashes is None:
515
+ return False
516
+ return any(hashes.is_hash_allowed(k, v) for k, v in self._hashes.items())
517
+
518
+
519
+ class _CleanResult(NamedTuple):
520
+ """Convert link for equivalency check.
521
+
522
+ This is used in the resolver to check whether two URL-specified requirements
523
+ likely point to the same distribution and can be considered equivalent. This
524
+ equivalency logic avoids comparing URLs literally, which can be too strict
525
+ (e.g. "a=1&b=2" vs "b=2&a=1") and produce conflicts unexpecting to users.
526
+
527
+ Currently this does three things:
528
+
529
+ 1. Drop the basic auth part. This is technically wrong since a server can
530
+ serve different content based on auth, but if it does that, it is even
531
+ impossible to guarantee two URLs without auth are equivalent, since
532
+ the user can input different auth information when prompted. So the
533
+ practical solution is to assume the auth doesn't affect the response.
534
+ 2. Parse the query to avoid the ordering issue. Note that ordering under the
535
+ same key in the query are NOT cleaned; i.e. "a=1&a=2" and "a=2&a=1" are
536
+ still considered different.
537
+ 3. Explicitly drop most of the fragment part, except ``subdirectory=`` and
538
+ hash values, since it should have no impact the downloaded content. Note
539
+ that this drops the "egg=" part historically used to denote the requested
540
+ project (and extras), which is wrong in the strictest sense, but too many
541
+ people are supplying it inconsistently to cause superfluous resolution
542
+ conflicts, so we choose to also ignore them.
543
+ """
544
+
545
+ parsed: urllib.parse.SplitResult
546
+ query: Dict[str, List[str]]
547
+ subdirectory: str
548
+ hashes: Dict[str, str]
549
+
550
+
551
+ def _clean_link(link: Link) -> _CleanResult:
552
+ parsed = link._parsed_url
553
+ netloc = parsed.netloc.rsplit("@", 1)[-1]
554
+ # According to RFC 8089, an empty host in file: means localhost.
555
+ if parsed.scheme == "file" and not netloc:
556
+ netloc = "localhost"
557
+ fragment = urllib.parse.parse_qs(parsed.fragment)
558
+ if "egg" in fragment:
559
+ logger.debug("Ignoring egg= fragment in %s", link)
560
+ try:
561
+ # If there are multiple subdirectory values, use the first one.
562
+ # This matches the behavior of Link.subdirectory_fragment.
563
+ subdirectory = fragment["subdirectory"][0]
564
+ except (IndexError, KeyError):
565
+ subdirectory = ""
566
+ # If there are multiple hash values under the same algorithm, use the
567
+ # first one. This matches the behavior of Link.hash_value.
568
+ hashes = {k: fragment[k][0] for k in _SUPPORTED_HASHES if k in fragment}
569
+ return _CleanResult(
570
+ parsed=parsed._replace(netloc=netloc, query="", fragment=""),
571
+ query=urllib.parse.parse_qs(parsed.query),
572
+ subdirectory=subdirectory,
573
+ hashes=hashes,
574
+ )
575
+
576
+
577
+ @functools.lru_cache(maxsize=None)
578
+ def links_equivalent(link1: Link, link2: Link) -> bool:
579
+ return _clean_link(link1) == _clean_link(link2)
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35/lib/python3.12/site-packages/pip/_internal/models/search_scope.py ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import itertools
2
+ import logging
3
+ import os
4
+ import posixpath
5
+ import urllib.parse
6
+ from typing import List
7
+
8
+ from pip._vendor.packaging.utils import canonicalize_name
9
+
10
+ from pip._internal.models.index import PyPI
11
+ from pip._internal.utils.compat import has_tls
12
+ from pip._internal.utils.misc import normalize_path, redact_auth_from_url
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ class SearchScope:
18
+
19
+ """
20
+ Encapsulates the locations that pip is configured to search.
21
+ """
22
+
23
+ __slots__ = ["find_links", "index_urls", "no_index"]
24
+
25
+ @classmethod
26
+ def create(
27
+ cls,
28
+ find_links: List[str],
29
+ index_urls: List[str],
30
+ no_index: bool,
31
+ ) -> "SearchScope":
32
+ """
33
+ Create a SearchScope object after normalizing the `find_links`.
34
+ """
35
+ # Build find_links. If an argument starts with ~, it may be
36
+ # a local file relative to a home directory. So try normalizing
37
+ # it and if it exists, use the normalized version.
38
+ # This is deliberately conservative - it might be fine just to
39
+ # blindly normalize anything starting with a ~...
40
+ built_find_links: List[str] = []
41
+ for link in find_links:
42
+ if link.startswith("~"):
43
+ new_link = normalize_path(link)
44
+ if os.path.exists(new_link):
45
+ link = new_link
46
+ built_find_links.append(link)
47
+
48
+ # If we don't have TLS enabled, then WARN if anyplace we're looking
49
+ # relies on TLS.
50
+ if not has_tls():
51
+ for link in itertools.chain(index_urls, built_find_links):
52
+ parsed = urllib.parse.urlparse(link)
53
+ if parsed.scheme == "https":
54
+ logger.warning(
55
+ "pip is configured with locations that require "
56
+ "TLS/SSL, however the ssl module in Python is not "
57
+ "available."
58
+ )
59
+ break
60
+
61
+ return cls(
62
+ find_links=built_find_links,
63
+ index_urls=index_urls,
64
+ no_index=no_index,
65
+ )
66
+
67
+ def __init__(
68
+ self,
69
+ find_links: List[str],
70
+ index_urls: List[str],
71
+ no_index: bool,
72
+ ) -> None:
73
+ self.find_links = find_links
74
+ self.index_urls = index_urls
75
+ self.no_index = no_index
76
+
77
+ def get_formatted_locations(self) -> str:
78
+ lines = []
79
+ redacted_index_urls = []
80
+ if self.index_urls and self.index_urls != [PyPI.simple_url]:
81
+ for url in self.index_urls:
82
+ redacted_index_url = redact_auth_from_url(url)
83
+
84
+ # Parse the URL
85
+ purl = urllib.parse.urlsplit(redacted_index_url)
86
+
87
+ # URL is generally invalid if scheme and netloc is missing
88
+ # there are issues with Python and URL parsing, so this test
89
+ # is a bit crude. See bpo-20271, bpo-23505. Python doesn't
90
+ # always parse invalid URLs correctly - it should raise
91
+ # exceptions for malformed URLs
92
+ if not purl.scheme and not purl.netloc:
93
+ logger.warning(
94
+ 'The index url "%s" seems invalid, please provide a scheme.',
95
+ redacted_index_url,
96
+ )
97
+
98
+ redacted_index_urls.append(redacted_index_url)
99
+
100
+ lines.append(
101
+ "Looking in indexes: {}".format(", ".join(redacted_index_urls))
102
+ )
103
+
104
+ if self.find_links:
105
+ lines.append(
106
+ "Looking in links: {}".format(
107
+ ", ".join(redact_auth_from_url(url) for url in self.find_links)
108
+ )
109
+ )
110
+ return "\n".join(lines)
111
+
112
+ def get_index_urls_locations(self, project_name: str) -> List[str]:
113
+ """Returns the locations found via self.index_urls
114
+
115
+ Checks the url_name on the main (first in the list) index and
116
+ use this url_name to produce all locations
117
+ """
118
+
119
+ def mkurl_pypi_url(url: str) -> str:
120
+ loc = posixpath.join(
121
+ url, urllib.parse.quote(canonicalize_name(project_name))
122
+ )
123
+ # For maximum compatibility with easy_install, ensure the path
124
+ # ends in a trailing slash. Although this isn't in the spec
125
+ # (and PyPI can handle it without the slash) some other index
126
+ # implementations might break if they relied on easy_install's
127
+ # behavior.
128
+ if not loc.endswith("/"):
129
+ loc = loc + "/"
130
+ return loc
131
+
132
+ return [mkurl_pypi_url(url) for url in self.index_urls]
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35/lib/python3.12/site-packages/pip/_internal/models/selection_prefs.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional
2
+
3
+ from pip._internal.models.format_control import FormatControl
4
+
5
+
6
+ class SelectionPreferences:
7
+ """
8
+ Encapsulates the candidate selection preferences for downloading
9
+ and installing files.
10
+ """
11
+
12
+ __slots__ = [
13
+ "allow_yanked",
14
+ "allow_all_prereleases",
15
+ "format_control",
16
+ "prefer_binary",
17
+ "ignore_requires_python",
18
+ ]
19
+
20
+ # Don't include an allow_yanked default value to make sure each call
21
+ # site considers whether yanked releases are allowed. This also causes
22
+ # that decision to be made explicit in the calling code, which helps
23
+ # people when reading the code.
24
+ def __init__(
25
+ self,
26
+ allow_yanked: bool,
27
+ allow_all_prereleases: bool = False,
28
+ format_control: Optional[FormatControl] = None,
29
+ prefer_binary: bool = False,
30
+ ignore_requires_python: Optional[bool] = None,
31
+ ) -> None:
32
+ """Create a SelectionPreferences object.
33
+
34
+ :param allow_yanked: Whether files marked as yanked (in the sense
35
+ of PEP 592) are permitted to be candidates for install.
36
+ :param format_control: A FormatControl object or None. Used to control
37
+ the selection of source packages / binary packages when consulting
38
+ the index and links.
39
+ :param prefer_binary: Whether to prefer an old, but valid, binary
40
+ dist over a new source dist.
41
+ :param ignore_requires_python: Whether to ignore incompatible
42
+ "Requires-Python" values in links. Defaults to False.
43
+ """
44
+ if ignore_requires_python is None:
45
+ ignore_requires_python = False
46
+
47
+ self.allow_yanked = allow_yanked
48
+ self.allow_all_prereleases = allow_all_prereleases
49
+ self.format_control = format_control
50
+ self.prefer_binary = prefer_binary
51
+ self.ignore_requires_python = ignore_requires_python
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35/lib/python3.12/site-packages/pip/_internal/models/wheel.py ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Represents a wheel file and provides access to the various parts of the
2
+ name that have meaning.
3
+ """
4
+ import re
5
+ from typing import Dict, Iterable, List
6
+
7
+ from pip._vendor.packaging.tags import Tag
8
+
9
+ from pip._internal.exceptions import InvalidWheelFilename
10
+
11
+
12
+ class Wheel:
13
+ """A wheel file"""
14
+
15
+ wheel_file_re = re.compile(
16
+ r"""^(?P<namever>(?P<name>[^\s-]+?)-(?P<ver>[^\s-]*?))
17
+ ((-(?P<build>\d[^-]*?))?-(?P<pyver>[^\s-]+?)-(?P<abi>[^\s-]+?)-(?P<plat>[^\s-]+?)
18
+ \.whl|\.dist-info)$""",
19
+ re.VERBOSE,
20
+ )
21
+
22
+ def __init__(self, filename: str) -> None:
23
+ """
24
+ :raises InvalidWheelFilename: when the filename is invalid for a wheel
25
+ """
26
+ wheel_info = self.wheel_file_re.match(filename)
27
+ if not wheel_info:
28
+ raise InvalidWheelFilename(f"{filename} is not a valid wheel filename.")
29
+ self.filename = filename
30
+ self.name = wheel_info.group("name").replace("_", "-")
31
+ # we'll assume "_" means "-" due to wheel naming scheme
32
+ # (https://github.com/pypa/pip/issues/1150)
33
+ self.version = wheel_info.group("ver").replace("_", "-")
34
+ self.build_tag = wheel_info.group("build")
35
+ self.pyversions = wheel_info.group("pyver").split(".")
36
+ self.abis = wheel_info.group("abi").split(".")
37
+ self.plats = wheel_info.group("plat").split(".")
38
+
39
+ # All the tag combinations from this file
40
+ self.file_tags = {
41
+ Tag(x, y, z) for x in self.pyversions for y in self.abis for z in self.plats
42
+ }
43
+
44
+ def get_formatted_file_tags(self) -> List[str]:
45
+ """Return the wheel's tags as a sorted list of strings."""
46
+ return sorted(str(tag) for tag in self.file_tags)
47
+
48
+ def support_index_min(self, tags: List[Tag]) -> int:
49
+ """Return the lowest index that one of the wheel's file_tag combinations
50
+ achieves in the given list of supported tags.
51
+
52
+ For example, if there are 8 supported tags and one of the file tags
53
+ is first in the list, then return 0.
54
+
55
+ :param tags: the PEP 425 tags to check the wheel against, in order
56
+ with most preferred first.
57
+
58
+ :raises ValueError: If none of the wheel's file tags match one of
59
+ the supported tags.
60
+ """
61
+ try:
62
+ return next(i for i, t in enumerate(tags) if t in self.file_tags)
63
+ except StopIteration:
64
+ raise ValueError()
65
+
66
+ def find_most_preferred_tag(
67
+ self, tags: List[Tag], tag_to_priority: Dict[Tag, int]
68
+ ) -> int:
69
+ """Return the priority of the most preferred tag that one of the wheel's file
70
+ tag combinations achieves in the given list of supported tags using the given
71
+ tag_to_priority mapping, where lower priorities are more-preferred.
72
+
73
+ This is used in place of support_index_min in some cases in order to avoid
74
+ an expensive linear scan of a large list of tags.
75
+
76
+ :param tags: the PEP 425 tags to check the wheel against.
77
+ :param tag_to_priority: a mapping from tag to priority of that tag, where
78
+ lower is more preferred.
79
+
80
+ :raises ValueError: If none of the wheel's file tags match one of
81
+ the supported tags.
82
+ """
83
+ return min(
84
+ tag_to_priority[tag] for tag in self.file_tags if tag in tag_to_priority
85
+ )
86
+
87
+ def supported(self, tags: Iterable[Tag]) -> bool:
88
+ """Return whether the wheel is compatible with one of the given tags.
89
+
90
+ :param tags: the PEP 425 tags to check the wheel against.
91
+ """
92
+ return not self.file_tags.isdisjoint(tags)
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/m2m_100/__init__.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2024 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ from typing import TYPE_CHECKING
15
+
16
+ from ...utils import _LazyModule
17
+ from ...utils.import_utils import define_import_structure
18
+
19
+
20
+ if TYPE_CHECKING:
21
+ from .configuration_m2m_100 import *
22
+ from .modeling_m2m_100 import *
23
+ from .tokenization_m2m_100 import *
24
+ else:
25
+ import sys
26
+
27
+ _file = globals()["__file__"]
28
+ sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/m2m_100/configuration_m2m_100.py ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2021 The Fairseq Authors and The HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """M2M100 model configuration"""
15
+
16
+ from huggingface_hub.dataclasses import strict
17
+
18
+ from ...configuration_utils import PreTrainedConfig
19
+ from ...utils import auto_docstring
20
+
21
+
22
+ @auto_docstring(checkpoint="facebook/m2m100_418M")
23
+ @strict
24
+ class M2M100Config(PreTrainedConfig):
25
+ r"""
26
+ Example:
27
+
28
+ ```python
29
+ >>> from transformers import M2M100Config, M2M100Model
30
+
31
+ >>> # Initializing a M2M100 facebook/m2m100_418M style configuration
32
+ >>> configuration = M2M100Config()
33
+
34
+ >>> # Initializing a model (with random weights) from the facebook/m2m100_418M style configuration
35
+ >>> model = M2M100Model(configuration)
36
+
37
+ >>> # Accessing the model configuration
38
+ >>> configuration = model.config
39
+ ```"""
40
+
41
+ model_type = "m2m_100"
42
+ keys_to_ignore_at_inference = ["past_key_values"]
43
+ attribute_map = {
44
+ "num_attention_heads": "encoder_attention_heads",
45
+ "hidden_size": "d_model",
46
+ "num_hidden_layers": "encoder_layers",
47
+ }
48
+
49
+ vocab_size: int = 128112
50
+ max_position_embeddings: int = 1024
51
+ encoder_layers: int = 12
52
+ encoder_ffn_dim: int = 4096
53
+ encoder_attention_heads: int = 16
54
+ decoder_layers: int = 12
55
+ decoder_ffn_dim: int = 4096
56
+ decoder_attention_heads: int = 16
57
+ encoder_layerdrop: float | int = 0.05
58
+ decoder_layerdrop: float | int = 0.05
59
+ use_cache: bool = True
60
+ is_encoder_decoder: bool = True
61
+ activation_function: str = "relu"
62
+ d_model: int = 1024
63
+ dropout: float | int = 0.1
64
+ attention_dropout: float | int = 0.1
65
+ activation_dropout: float | int = 0.0
66
+ init_std: float = 0.02
67
+ decoder_start_token_id: int | None = 2
68
+ scale_embedding: bool = True
69
+ pad_token_id: int | None = 1
70
+ bos_token_id: int | None = 0
71
+ eos_token_id: int | list[int] | None = 2
72
+ tie_word_embeddings: bool = True
73
+
74
+
75
+ __all__ = ["M2M100Config"]
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/m2m_100/modeling_m2m_100.py ADDED
@@ -0,0 +1,923 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2021 The Fairseq Authors and The HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """PyTorch M2M100 model."""
15
+
16
+ import math
17
+ from collections.abc import Callable
18
+
19
+ import torch
20
+ from torch import nn
21
+ from torch.nn import CrossEntropyLoss
22
+
23
+ from ... import initialization as init
24
+ from ...activations import ACT2FN
25
+ from ...cache_utils import Cache, DynamicCache, EncoderDecoderCache
26
+ from ...generation import GenerationMixin
27
+ from ...masking_utils import create_bidirectional_mask, create_causal_mask
28
+ from ...modeling_flash_attention_utils import (
29
+ FlashAttentionKwargs,
30
+ )
31
+ from ...modeling_layers import GradientCheckpointingLayer
32
+ from ...modeling_outputs import (
33
+ BaseModelOutput,
34
+ BaseModelOutputWithPastAndCrossAttentions,
35
+ Seq2SeqLMOutput,
36
+ Seq2SeqModelOutput,
37
+ )
38
+ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
39
+ from ...processing_utils import Unpack
40
+ from ...utils import TransformersKwargs, auto_docstring, is_torchdynamo_compiling, logging
41
+ from ...utils.generic import merge_with_config_defaults
42
+ from ...utils.output_capturing import OutputRecorder, capture_outputs
43
+ from .configuration_m2m_100 import M2M100Config
44
+
45
+
46
+ logger = logging.get_logger(__name__)
47
+
48
+
49
+ # Copied from transformers.models.bart.modeling_bart.shift_tokens_right
50
+ def shift_tokens_right(input_ids: torch.Tensor, pad_token_id: int, decoder_start_token_id: int):
51
+ """
52
+ Shift input ids one token to the right.
53
+ """
54
+ shifted_input_ids = input_ids.new_zeros(input_ids.shape)
55
+ shifted_input_ids[:, 1:] = input_ids[:, :-1].clone()
56
+ shifted_input_ids[:, 0] = decoder_start_token_id
57
+
58
+ if pad_token_id is None:
59
+ raise ValueError("self.model.config.pad_token_id has to be defined.")
60
+ # replace possible -100 values in labels by `pad_token_id`
61
+ shifted_input_ids.masked_fill_(shifted_input_ids == -100, pad_token_id)
62
+
63
+ return shifted_input_ids
64
+
65
+
66
+ # Copied from transformers.models.bart.modeling_bart.BartScaledWordEmbedding with Bart->M2M100
67
+ class M2M100ScaledWordEmbedding(nn.Embedding):
68
+ """
69
+ This module overrides nn.Embeddings' forward by multiplying with embeddings scale.
70
+ """
71
+
72
+ def __init__(self, num_embeddings: int, embedding_dim: int, padding_idx: int, embed_scale: float | None = 1.0):
73
+ super().__init__(num_embeddings, embedding_dim, padding_idx)
74
+ self.embed_scale = embed_scale
75
+
76
+ def forward(self, input_ids: torch.Tensor):
77
+ return super().forward(input_ids) * self.embed_scale
78
+
79
+
80
+ class M2M100SinusoidalPositionalEmbedding(nn.Module):
81
+ """This module produces sinusoidal positional embeddings of any length."""
82
+
83
+ def __init__(self, num_positions: int, embedding_dim: int, padding_idx: int | None = None):
84
+ super().__init__()
85
+ self.offset = 2
86
+ self.num_positions = num_positions
87
+ self.embedding_dim = embedding_dim
88
+ self.padding_idx = padding_idx
89
+ self.make_weights(num_positions + self.offset, embedding_dim, padding_idx)
90
+
91
+ def make_weights(self, num_embeddings: int, embedding_dim: int, padding_idx: int | None = None):
92
+ emb_weights = self.get_embedding(num_embeddings, embedding_dim, padding_idx)
93
+ if hasattr(self, "weights"):
94
+ # in forward put the weights on the correct dtype and device of the param
95
+ emb_weights = emb_weights.to(dtype=self.weights.dtype, device=self.weights.device)
96
+
97
+ self.register_buffer("weights", emb_weights, persistent=False)
98
+
99
+ @staticmethod
100
+ def get_embedding(num_embeddings: int, embedding_dim: int, padding_idx: int | None = None):
101
+ """
102
+ Build sinusoidal embeddings.
103
+
104
+ This matches the implementation in tensor2tensor, but differs slightly from the description in Section 3.5 of
105
+ "Attention Is All You Need".
106
+ """
107
+ half_dim = embedding_dim // 2
108
+ emb = math.log(10000) / (half_dim - 1)
109
+ emb = torch.exp(torch.arange(half_dim, dtype=torch.int64).float() * -emb)
110
+ emb = torch.arange(num_embeddings, dtype=torch.int64).float().unsqueeze(1) * emb.unsqueeze(0)
111
+ emb = torch.cat([torch.sin(emb), torch.cos(emb)], dim=1).view(num_embeddings, -1)
112
+ if embedding_dim % 2 == 1:
113
+ # zero pad
114
+ emb = torch.cat([emb, torch.zeros(num_embeddings, 1)], dim=1)
115
+ if padding_idx is not None:
116
+ emb[padding_idx, :] = 0
117
+
118
+ return emb.to(torch.get_default_dtype())
119
+
120
+ @torch.no_grad()
121
+ def forward(
122
+ self,
123
+ input_ids: torch.Tensor | None = None,
124
+ inputs_embeds: torch.Tensor | None = None,
125
+ past_key_values_length: int = 0,
126
+ ):
127
+ if input_ids is not None:
128
+ bsz, seq_len = input_ids.size()
129
+ # Create the position ids from the input token ids. Any padded tokens remain padded.
130
+ position_ids = self.create_position_ids_from_input_ids(
131
+ input_ids, self.padding_idx, past_key_values_length
132
+ ).to(input_ids.device)
133
+ else:
134
+ bsz, seq_len = inputs_embeds.size()[:-1]
135
+ position_ids = self.create_position_ids_from_inputs_embeds(
136
+ inputs_embeds, past_key_values_length, self.padding_idx
137
+ )
138
+
139
+ # expand embeddings if needed
140
+ max_pos = self.padding_idx + 1 + seq_len + past_key_values_length
141
+ if max_pos > self.weights.size(0):
142
+ self.make_weights(max_pos + self.offset, self.embedding_dim, self.padding_idx)
143
+
144
+ return self.weights.index_select(0, position_ids.view(-1)).view(bsz, seq_len, self.weights.shape[-1]).detach()
145
+
146
+ @staticmethod
147
+ def create_position_ids_from_inputs_embeds(inputs_embeds, past_key_values_length, padding_idx):
148
+ """
149
+ We are provided embeddings directly. We cannot infer which are padded so just generate sequential position ids.
150
+
151
+ Args:
152
+ inputs_embeds: torch.Tensor
153
+
154
+ Returns: torch.Tensor
155
+ """
156
+ input_shape = inputs_embeds.size()[:-1]
157
+ sequence_length = input_shape[1]
158
+
159
+ position_ids = torch.arange(
160
+ padding_idx + 1, sequence_length + padding_idx + 1, dtype=torch.long, device=inputs_embeds.device
161
+ )
162
+ return position_ids.unsqueeze(0).expand(input_shape).contiguous() + past_key_values_length
163
+
164
+ @staticmethod
165
+ # Copied from transformers.models.roberta.modeling_roberta.RobertaEmbeddings.create_position_ids_from_input_ids
166
+ def create_position_ids_from_input_ids(input_ids, padding_idx, past_key_values_length=0):
167
+ """
168
+ Replace non-padding symbols with their position numbers. Position numbers begin at padding_idx+1. Padding symbols
169
+ are ignored. This is modified from fairseq's `utils.make_positions`.
170
+
171
+ Args:
172
+ x: torch.Tensor x:
173
+
174
+ Returns: torch.Tensor
175
+ """
176
+ # The series of casts and type-conversions here are carefully balanced to both work with ONNX export and XLA.
177
+ mask = input_ids.ne(padding_idx).int()
178
+ incremental_indices = (torch.cumsum(mask, dim=1).type_as(mask) + past_key_values_length) * mask
179
+ return incremental_indices.long() + padding_idx
180
+
181
+
182
+ # Copied from transformers.models.bert.modeling_bert.eager_attention_forward
183
+ def eager_attention_forward(
184
+ module: nn.Module,
185
+ query: torch.Tensor,
186
+ key: torch.Tensor,
187
+ value: torch.Tensor,
188
+ attention_mask: torch.Tensor | None,
189
+ scaling: float | None = None,
190
+ dropout: float = 0.0,
191
+ **kwargs: Unpack[TransformersKwargs],
192
+ ):
193
+ if scaling is None:
194
+ scaling = query.size(-1) ** -0.5
195
+
196
+ # Take the dot product between "query" and "key" to get the raw attention scores.
197
+ attn_weights = torch.matmul(query, key.transpose(2, 3)) * scaling
198
+
199
+ if attention_mask is not None:
200
+ attn_weights = attn_weights + attention_mask
201
+
202
+ attn_weights = nn.functional.softmax(attn_weights, dim=-1)
203
+ attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
204
+
205
+ attn_output = torch.matmul(attn_weights, value)
206
+ attn_output = attn_output.transpose(1, 2).contiguous()
207
+
208
+ return attn_output, attn_weights
209
+
210
+
211
+ # Copied from transformers.models.bart.modeling_bart.BartAttention with Bart->M2M100
212
+ class M2M100Attention(nn.Module):
213
+ """Multi-headed attention from 'Attention Is All You Need' paper"""
214
+
215
+ def __init__(
216
+ self,
217
+ embed_dim: int,
218
+ num_heads: int,
219
+ dropout: float = 0.0,
220
+ is_decoder: bool = False,
221
+ bias: bool = True,
222
+ is_causal: bool = False,
223
+ config: M2M100Config | None = None,
224
+ layer_idx: int | None = None,
225
+ ):
226
+ super().__init__()
227
+ self.embed_dim = embed_dim
228
+ self.num_heads = num_heads
229
+ self.dropout = dropout
230
+ self.head_dim = embed_dim // num_heads
231
+ self.config = config
232
+
233
+ if (self.head_dim * num_heads) != self.embed_dim:
234
+ raise ValueError(
235
+ f"embed_dim must be divisible by num_heads (got `embed_dim`: {self.embed_dim}"
236
+ f" and `num_heads`: {num_heads})."
237
+ )
238
+ self.scaling = self.head_dim**-0.5
239
+ self.is_decoder = is_decoder
240
+ self.is_causal = is_causal
241
+ self.layer_idx = layer_idx
242
+ if layer_idx is None and self.is_decoder:
243
+ logger.warning_once(
244
+ f"Instantiating a decoder {self.__class__.__name__} without passing `layer_idx` is not recommended and "
245
+ "will lead to errors during the forward call, if caching is used. Please make sure to provide a `layer_idx` "
246
+ "when creating this class."
247
+ )
248
+
249
+ self.k_proj = nn.Linear(embed_dim, embed_dim, bias=bias)
250
+ self.v_proj = nn.Linear(embed_dim, embed_dim, bias=bias)
251
+ self.q_proj = nn.Linear(embed_dim, embed_dim, bias=bias)
252
+ self.out_proj = nn.Linear(embed_dim, embed_dim, bias=bias)
253
+
254
+ def forward(
255
+ self,
256
+ hidden_states: torch.Tensor,
257
+ key_value_states: torch.Tensor | None = None,
258
+ past_key_values: Cache | None = None,
259
+ attention_mask: torch.Tensor | None = None,
260
+ # TODO: we need a refactor so that the different attention modules can get their specific kwargs
261
+ # ATM, we have mixed things encoder, decoder, and encoder-decoder attn
262
+ **kwargs: Unpack[FlashAttentionKwargs],
263
+ ) -> tuple[torch.Tensor, torch.Tensor | None]:
264
+ """Input shape: Batch x Time x Channel"""
265
+
266
+ # if key_value_states are provided this layer is used as a cross-attention layer
267
+ # for the decoder
268
+ is_cross_attention = key_value_states is not None
269
+
270
+ # determine input shapes
271
+ input_shape = hidden_states.shape[:-1]
272
+
273
+ hidden_shape = (*input_shape, -1, self.head_dim)
274
+
275
+ # get query proj
276
+ query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2)
277
+
278
+ is_updated = False
279
+ if past_key_values is not None:
280
+ if isinstance(past_key_values, EncoderDecoderCache):
281
+ is_updated = past_key_values.is_updated.get(self.layer_idx)
282
+ if is_cross_attention:
283
+ # after the first generated id, we can subsequently re-use all key/value_states from cache
284
+ curr_past_key_values = past_key_values.cross_attention_cache
285
+ else:
286
+ curr_past_key_values = past_key_values.self_attention_cache
287
+ else:
288
+ curr_past_key_values = past_key_values
289
+
290
+ current_states = key_value_states if is_cross_attention else hidden_states
291
+ if is_cross_attention and past_key_values is not None and is_updated:
292
+ # reuse k,v, cross_attentions
293
+ key_states = curr_past_key_values.layers[self.layer_idx].keys
294
+ value_states = curr_past_key_values.layers[self.layer_idx].values
295
+ else:
296
+ key_states = self.k_proj(current_states)
297
+ value_states = self.v_proj(current_states)
298
+ kv_shape = (*current_states.shape[:-1], -1, self.head_dim)
299
+ key_states = key_states.view(kv_shape).transpose(1, 2)
300
+ value_states = value_states.view(kv_shape).transpose(1, 2)
301
+
302
+ if past_key_values is not None:
303
+ key_states, value_states = curr_past_key_values.update(key_states, value_states, self.layer_idx)
304
+ # set flag that curr layer for cross-attn is already updated so we can re-use in subsequent calls
305
+ if is_cross_attention and isinstance(past_key_values, EncoderDecoderCache):
306
+ past_key_values.is_updated[self.layer_idx] = True
307
+
308
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
309
+ self.config._attn_implementation, eager_attention_forward
310
+ )
311
+
312
+ attn_output, attn_weights = attention_interface(
313
+ self,
314
+ query_states,
315
+ key_states,
316
+ value_states,
317
+ attention_mask,
318
+ dropout=0.0 if not self.training else self.dropout,
319
+ scaling=self.scaling,
320
+ **kwargs,
321
+ )
322
+
323
+ attn_output = attn_output.reshape(*input_shape, -1).contiguous()
324
+ attn_output = self.out_proj(attn_output)
325
+
326
+ return attn_output, attn_weights
327
+
328
+
329
+ # Copied from transformers.models.mbart.modeling_mbart.MBartEncoderLayer with MBart->M2M100, MBART->M2M100
330
+ class M2M100EncoderLayer(GradientCheckpointingLayer):
331
+ def __init__(self, config: M2M100Config):
332
+ super().__init__()
333
+ self.embed_dim = config.d_model
334
+
335
+ self.self_attn = M2M100Attention(
336
+ embed_dim=self.embed_dim,
337
+ num_heads=config.encoder_attention_heads,
338
+ dropout=config.attention_dropout,
339
+ config=config,
340
+ )
341
+ self.self_attn_layer_norm = nn.LayerNorm(self.embed_dim)
342
+ self.dropout = config.dropout
343
+ self.activation_fn = ACT2FN[config.activation_function]
344
+ self.activation_dropout = config.activation_dropout
345
+ self.fc1 = nn.Linear(self.embed_dim, config.encoder_ffn_dim)
346
+ self.fc2 = nn.Linear(config.encoder_ffn_dim, self.embed_dim)
347
+ self.final_layer_norm = nn.LayerNorm(self.embed_dim)
348
+
349
+ def forward(
350
+ self,
351
+ hidden_states: torch.Tensor,
352
+ attention_mask: torch.Tensor,
353
+ **kwargs: Unpack[TransformersKwargs],
354
+ ) -> torch.Tensor:
355
+ """
356
+ Args:
357
+ hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)`
358
+ attention_mask (`torch.FloatTensor`): attention mask of size
359
+ `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values.
360
+ """
361
+ residual = hidden_states
362
+ hidden_states = self.self_attn_layer_norm(hidden_states)
363
+ hidden_states, _ = self.self_attn(
364
+ hidden_states=hidden_states,
365
+ attention_mask=attention_mask,
366
+ **kwargs,
367
+ )
368
+ hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
369
+ hidden_states = residual + hidden_states
370
+
371
+ residual = hidden_states
372
+ hidden_states = self.final_layer_norm(hidden_states)
373
+ hidden_states = self.activation_fn(self.fc1(hidden_states))
374
+ hidden_states = nn.functional.dropout(hidden_states, p=self.activation_dropout, training=self.training)
375
+ hidden_states = self.fc2(hidden_states)
376
+ hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
377
+ hidden_states = residual + hidden_states
378
+
379
+ if hidden_states.dtype == torch.float16:
380
+ clamp_value = torch.finfo(hidden_states.dtype).max - 1000
381
+ hidden_states = torch.clamp(hidden_states, min=-clamp_value, max=clamp_value)
382
+
383
+ return hidden_states
384
+
385
+
386
+ # Copied from transformers.models.mbart.modeling_mbart.MBartDecoderLayer with MBart->M2M100, MBART->M2M100
387
+ class M2M100DecoderLayer(GradientCheckpointingLayer):
388
+ def __init__(self, config: M2M100Config, layer_idx: int | None = None):
389
+ super().__init__()
390
+ self.embed_dim = config.d_model
391
+
392
+ self.self_attn = M2M100Attention(
393
+ embed_dim=self.embed_dim,
394
+ num_heads=config.decoder_attention_heads,
395
+ dropout=config.attention_dropout,
396
+ is_decoder=True,
397
+ is_causal=True,
398
+ config=config,
399
+ layer_idx=layer_idx,
400
+ )
401
+ self.dropout = config.dropout
402
+ self.activation_fn = ACT2FN[config.activation_function]
403
+ self.activation_dropout = config.activation_dropout
404
+
405
+ self.self_attn_layer_norm = nn.LayerNorm(self.embed_dim)
406
+ self.encoder_attn = M2M100Attention(
407
+ self.embed_dim,
408
+ config.decoder_attention_heads,
409
+ dropout=config.attention_dropout,
410
+ is_decoder=True,
411
+ config=config,
412
+ layer_idx=layer_idx,
413
+ )
414
+ self.encoder_attn_layer_norm = nn.LayerNorm(self.embed_dim)
415
+ self.fc1 = nn.Linear(self.embed_dim, config.decoder_ffn_dim)
416
+ self.fc2 = nn.Linear(config.decoder_ffn_dim, self.embed_dim)
417
+ self.final_layer_norm = nn.LayerNorm(self.embed_dim)
418
+
419
+ def forward(
420
+ self,
421
+ hidden_states: torch.Tensor,
422
+ attention_mask: torch.Tensor | None = None,
423
+ encoder_hidden_states: torch.Tensor | None = None,
424
+ encoder_attention_mask: torch.Tensor | None = None,
425
+ past_key_values: Cache | None = None,
426
+ use_cache: bool | None = True,
427
+ **kwargs: Unpack[TransformersKwargs],
428
+ ) -> torch.Tensor:
429
+ """
430
+ Args:
431
+ hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)`
432
+ attention_mask (`torch.FloatTensor`): attention mask of size
433
+ `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values.
434
+ encoder_hidden_states (`torch.FloatTensor`):
435
+ cross attention input to the layer of shape `(batch, seq_len, embed_dim)`
436
+ encoder_attention_mask (`torch.FloatTensor`): encoder attention mask of size
437
+ `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values.
438
+ past_key_values (`Cache`): cached past key and value projection states
439
+ """
440
+ residual = hidden_states
441
+ hidden_states = self.self_attn_layer_norm(hidden_states)
442
+
443
+ # Self Attention
444
+ hidden_states, _ = self.self_attn(
445
+ hidden_states=hidden_states,
446
+ past_key_values=past_key_values,
447
+ attention_mask=attention_mask,
448
+ **kwargs,
449
+ )
450
+ hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
451
+ hidden_states = residual + hidden_states
452
+
453
+ # Cross-Attention Block
454
+ if encoder_hidden_states is not None:
455
+ residual = hidden_states
456
+ hidden_states = self.encoder_attn_layer_norm(hidden_states)
457
+
458
+ hidden_states, _ = self.encoder_attn(
459
+ hidden_states=hidden_states,
460
+ key_value_states=encoder_hidden_states,
461
+ attention_mask=encoder_attention_mask,
462
+ past_key_values=past_key_values,
463
+ **kwargs,
464
+ )
465
+ hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
466
+ hidden_states = residual + hidden_states
467
+
468
+ # Fully Connected
469
+ residual = hidden_states
470
+ hidden_states = self.final_layer_norm(hidden_states)
471
+ hidden_states = self.activation_fn(self.fc1(hidden_states))
472
+ hidden_states = nn.functional.dropout(hidden_states, p=self.activation_dropout, training=self.training)
473
+ hidden_states = self.fc2(hidden_states)
474
+ hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
475
+ hidden_states = residual + hidden_states
476
+
477
+ return hidden_states
478
+
479
+
480
+ @auto_docstring
481
+ class M2M100PreTrainedModel(PreTrainedModel):
482
+ config: M2M100Config
483
+ base_model_prefix = "model"
484
+ supports_gradient_checkpointing = True
485
+ _no_split_modules = ["M2M100EncoderLayer", "M2M100DecoderLayer"]
486
+ _supports_flash_attn = True
487
+ _supports_sdpa = True
488
+ _supports_flex_attn = True
489
+ # Doesn't support `compile` (dynamic control flow). Can be fixed but low usage model
490
+ _can_compile_fullgraph = False
491
+
492
+ def _init_weights(self, module):
493
+ super()._init_weights(module)
494
+ if isinstance(module, M2M100SinusoidalPositionalEmbedding):
495
+ emb_weights = module.get_embedding(
496
+ module.num_positions + module.offset, module.embedding_dim, module.padding_idx
497
+ )
498
+ init.copy_(module.weights, emb_weights)
499
+
500
+
501
+ class M2M100Encoder(M2M100PreTrainedModel):
502
+ """
503
+ Transformer encoder consisting of *config.encoder_layers* self attention layers. Each layer is a
504
+ [`M2M100EncoderLayer`].
505
+
506
+ Args:
507
+ config: M2M100Config
508
+ embed_tokens (nn.Embedding): output embedding
509
+ """
510
+
511
+ _can_record_outputs = {
512
+ "hidden_states": M2M100EncoderLayer,
513
+ "attentions": M2M100Attention,
514
+ }
515
+
516
+ def __init__(self, config: M2M100Config):
517
+ super().__init__(config)
518
+
519
+ self.dropout = config.dropout
520
+ self.layerdrop = config.encoder_layerdrop
521
+
522
+ embed_dim = config.d_model
523
+ self.padding_idx = config.pad_token_id
524
+ self.max_source_positions = config.max_position_embeddings
525
+ embed_scale = math.sqrt(embed_dim) if config.scale_embedding else 1.0
526
+
527
+ self.embed_tokens = M2M100ScaledWordEmbedding(
528
+ config.vocab_size, embed_dim, self.padding_idx, embed_scale=embed_scale
529
+ )
530
+
531
+ self.embed_positions = M2M100SinusoidalPositionalEmbedding(
532
+ config.max_position_embeddings,
533
+ embed_dim,
534
+ self.padding_idx,
535
+ )
536
+ self.layers = nn.ModuleList([M2M100EncoderLayer(config) for _ in range(config.encoder_layers)])
537
+ self.layer_norm = nn.LayerNorm(config.d_model)
538
+
539
+ self.gradient_checkpointing = False
540
+ # Initialize weights and apply final processing
541
+ self.post_init()
542
+
543
+ @merge_with_config_defaults
544
+ @capture_outputs
545
+ @auto_docstring
546
+ def forward(
547
+ self,
548
+ input_ids: torch.Tensor | None = None,
549
+ attention_mask: torch.Tensor | None = None,
550
+ inputs_embeds: torch.Tensor | None = None,
551
+ **kwargs: Unpack[TransformersKwargs],
552
+ ) -> BaseModelOutput:
553
+ if (input_ids is None) ^ (inputs_embeds is not None):
554
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
555
+
556
+ if inputs_embeds is None:
557
+ inputs_embeds = self.embed_tokens(input_ids)
558
+
559
+ embed_pos = self.embed_positions(input_ids, inputs_embeds)
560
+ embed_pos = embed_pos.to(inputs_embeds.device)
561
+
562
+ hidden_states = inputs_embeds + embed_pos
563
+ hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
564
+
565
+ attention_mask = create_bidirectional_mask(
566
+ config=self.config,
567
+ inputs_embeds=inputs_embeds,
568
+ attention_mask=attention_mask,
569
+ )
570
+
571
+ for idx, encoder_layer in enumerate(self.layers):
572
+ # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description)
573
+ to_drop = False
574
+ if self.training:
575
+ dropout_probability = torch.rand([])
576
+ if dropout_probability < self.layerdrop:
577
+ to_drop = True
578
+
579
+ if not to_drop:
580
+ hidden_states = encoder_layer(
581
+ hidden_states,
582
+ attention_mask,
583
+ **kwargs,
584
+ )
585
+
586
+ hidden_states = self.layer_norm(hidden_states)
587
+
588
+ return BaseModelOutput(
589
+ last_hidden_state=hidden_states,
590
+ )
591
+
592
+
593
+ class M2M100Decoder(M2M100PreTrainedModel):
594
+ """
595
+ Transformer decoder consisting of *config.decoder_layers* layers. Each layer is a [`M2M100DecoderLayer`]
596
+
597
+ Args:
598
+ config: M2M100Config
599
+ embed_tokens (nn.Embedding): output embedding
600
+ """
601
+
602
+ _can_record_outputs = {
603
+ "hidden_states": M2M100DecoderLayer,
604
+ "attentions": OutputRecorder(M2M100Attention, index=1, layer_name="self_attn"),
605
+ "cross_attentions": OutputRecorder(M2M100Attention, index=1, layer_name="encoder_attn"),
606
+ }
607
+
608
+ def __init__(self, config: M2M100Config):
609
+ super().__init__(config)
610
+ self.dropout = config.dropout
611
+ self.layerdrop = config.decoder_layerdrop
612
+ self.padding_idx = config.pad_token_id
613
+ self.max_target_positions = config.max_position_embeddings
614
+ embed_scale = math.sqrt(config.d_model) if config.scale_embedding else 1.0
615
+
616
+ self.embed_tokens = M2M100ScaledWordEmbedding(
617
+ config.vocab_size, config.d_model, self.padding_idx, embed_scale=embed_scale
618
+ )
619
+
620
+ self.embed_positions = M2M100SinusoidalPositionalEmbedding(
621
+ config.max_position_embeddings,
622
+ config.d_model,
623
+ self.padding_idx,
624
+ )
625
+ self.layers = nn.ModuleList([M2M100DecoderLayer(config, layer_idx=i) for i in range(config.decoder_layers)])
626
+ self.layer_norm = nn.LayerNorm(config.d_model)
627
+
628
+ self.gradient_checkpointing = False
629
+ # Initialize weights and apply final processing
630
+ self.post_init()
631
+
632
+ @merge_with_config_defaults
633
+ @capture_outputs
634
+ @auto_docstring
635
+ def forward(
636
+ self,
637
+ input_ids: torch.Tensor | None = None,
638
+ attention_mask: torch.Tensor | None = None,
639
+ encoder_hidden_states: torch.Tensor | None = None,
640
+ encoder_attention_mask: torch.Tensor | None = None,
641
+ past_key_values: Cache | None = None,
642
+ inputs_embeds: torch.Tensor | None = None,
643
+ use_cache: bool | None = None,
644
+ **kwargs: Unpack[TransformersKwargs],
645
+ ) -> BaseModelOutputWithPastAndCrossAttentions:
646
+ if (input_ids is None) ^ (inputs_embeds is not None):
647
+ raise ValueError("You cannot specify both decoder_input_ids and decoder_inputs_embeds at the same time")
648
+
649
+ if inputs_embeds is None:
650
+ inputs_embeds = self.embed_tokens(input_ids)
651
+
652
+ # initialize `past_key_values`
653
+ if use_cache and past_key_values is None:
654
+ past_key_values = EncoderDecoderCache(DynamicCache(config=self.config), DynamicCache(config=self.config))
655
+
656
+ batch_size, seq_length = inputs_embeds.size()[:-1]
657
+ past_key_values_length = past_key_values.get_seq_length() if past_key_values is not None else 0
658
+
659
+ if attention_mask is None and not is_torchdynamo_compiling():
660
+ # required mask seq length can be calculated via length of past cache
661
+ mask_seq_length = past_key_values_length + seq_length
662
+ attention_mask = torch.ones(batch_size, mask_seq_length, device=inputs_embeds.device)
663
+
664
+ self_attn_cache = (
665
+ past_key_values.self_attention_cache
666
+ if isinstance(past_key_values, EncoderDecoderCache)
667
+ else past_key_values
668
+ )
669
+
670
+ attention_mask = create_causal_mask(
671
+ config=self.config,
672
+ inputs_embeds=inputs_embeds,
673
+ attention_mask=attention_mask,
674
+ past_key_values=self_attn_cache,
675
+ )
676
+ encoder_attention_mask = create_bidirectional_mask(
677
+ config=self.config,
678
+ inputs_embeds=inputs_embeds,
679
+ attention_mask=encoder_attention_mask,
680
+ encoder_hidden_states=encoder_hidden_states,
681
+ )
682
+
683
+ # embed positions
684
+ positions = self.embed_positions(input_ids, inputs_embeds, past_key_values_length)
685
+ positions = positions.to(inputs_embeds.device)
686
+
687
+ hidden_states = inputs_embeds + positions
688
+ hidden_states = nn.functional.dropout(hidden_states, p=self.dropout, training=self.training)
689
+
690
+ for idx, decoder_layer in enumerate(self.layers):
691
+ # add LayerDrop (see https://huggingface.co/papers/1909.11556 for description)
692
+ if self.training:
693
+ dropout_probability = torch.rand([])
694
+ if dropout_probability < self.layerdrop:
695
+ continue
696
+
697
+ hidden_states = decoder_layer(
698
+ hidden_states,
699
+ attention_mask,
700
+ encoder_hidden_states, # as a positional argument for gradient checkpointing
701
+ encoder_attention_mask=encoder_attention_mask,
702
+ past_key_values=past_key_values,
703
+ use_cache=use_cache,
704
+ **kwargs,
705
+ )
706
+
707
+ hidden_states = self.layer_norm(hidden_states)
708
+
709
+ return BaseModelOutputWithPastAndCrossAttentions(
710
+ last_hidden_state=hidden_states,
711
+ past_key_values=past_key_values,
712
+ )
713
+
714
+
715
+ @auto_docstring
716
+ class M2M100Model(M2M100PreTrainedModel):
717
+ _tied_weights_keys = {
718
+ "decoder.embed_tokens.weight": "shared.weight",
719
+ "encoder.embed_tokens.weight": "shared.weight",
720
+ }
721
+
722
+ def __init__(self, config: M2M100Config):
723
+ super().__init__(config)
724
+
725
+ padding_idx, vocab_size = config.pad_token_id, config.vocab_size
726
+ embed_scale = math.sqrt(config.d_model) if config.scale_embedding else 1.0
727
+ self.shared = M2M100ScaledWordEmbedding(vocab_size, config.d_model, padding_idx, embed_scale=embed_scale)
728
+
729
+ self.encoder = M2M100Encoder(config)
730
+ self.decoder = M2M100Decoder(config)
731
+
732
+ # Initialize weights and apply final processing
733
+ self.post_init()
734
+
735
+ def get_input_embeddings(self):
736
+ return self.shared
737
+
738
+ def set_input_embeddings(self, value):
739
+ self.shared = value
740
+ self.encoder.embed_tokens = self.shared
741
+ self.decoder.embed_tokens = self.shared
742
+
743
+ @merge_with_config_defaults
744
+ @capture_outputs
745
+ @auto_docstring
746
+ def forward(
747
+ self,
748
+ input_ids: torch.LongTensor | None = None,
749
+ attention_mask: torch.Tensor | None = None,
750
+ decoder_input_ids: torch.LongTensor | None = None,
751
+ decoder_attention_mask: torch.LongTensor | None = None,
752
+ encoder_outputs: tuple[tuple[torch.FloatTensor]] | None = None,
753
+ past_key_values: Cache | None = None,
754
+ inputs_embeds: torch.FloatTensor | None = None,
755
+ decoder_inputs_embeds: torch.FloatTensor | None = None,
756
+ use_cache: bool | None = None,
757
+ **kwargs: Unpack[TransformersKwargs],
758
+ ) -> tuple[torch.Tensor] | Seq2SeqModelOutput:
759
+ r"""
760
+ decoder_input_ids (`torch.LongTensor` of shape `(batch_size, target_sequence_length)`, *optional*):
761
+ Indices of decoder input sequence tokens in the vocabulary.
762
+
763
+ Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
764
+ [`PreTrainedTokenizer.__call__`] for details.
765
+
766
+ [What are decoder input IDs?](../glossary#decoder-input-ids)
767
+
768
+ M2M100 uses the `eos_token_id` as the starting token for `decoder_input_ids` generation. If
769
+ `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see
770
+ `past_key_values`).
771
+ decoder_attention_mask (`torch.LongTensor` of shape `(batch_size, target_sequence_length)`, *optional*):
772
+ Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also
773
+ be used by default.
774
+ """
775
+ if encoder_outputs is None:
776
+ encoder_outputs = self.encoder(
777
+ input_ids=input_ids,
778
+ attention_mask=attention_mask,
779
+ inputs_embeds=inputs_embeds,
780
+ **kwargs,
781
+ )
782
+ elif not isinstance(encoder_outputs, BaseModelOutput):
783
+ encoder_outputs = BaseModelOutput(
784
+ last_hidden_state=encoder_outputs[0],
785
+ hidden_states=encoder_outputs[1] if len(encoder_outputs) > 1 else None,
786
+ attentions=encoder_outputs[2] if len(encoder_outputs) > 2 else None,
787
+ )
788
+
789
+ # decoder outputs consists of (dec_features, past_key_values, dec_hidden, dec_attn)
790
+ decoder_outputs = self.decoder(
791
+ input_ids=decoder_input_ids,
792
+ attention_mask=decoder_attention_mask,
793
+ encoder_hidden_states=encoder_outputs[0],
794
+ encoder_attention_mask=attention_mask,
795
+ past_key_values=past_key_values,
796
+ inputs_embeds=decoder_inputs_embeds,
797
+ use_cache=use_cache,
798
+ **kwargs,
799
+ )
800
+
801
+ return Seq2SeqModelOutput(
802
+ last_hidden_state=decoder_outputs.last_hidden_state,
803
+ past_key_values=decoder_outputs.past_key_values,
804
+ decoder_hidden_states=decoder_outputs.hidden_states,
805
+ decoder_attentions=decoder_outputs.attentions,
806
+ cross_attentions=decoder_outputs.cross_attentions,
807
+ encoder_last_hidden_state=encoder_outputs.last_hidden_state,
808
+ encoder_hidden_states=encoder_outputs.hidden_states,
809
+ encoder_attentions=encoder_outputs.attentions,
810
+ )
811
+
812
+
813
+ @auto_docstring(
814
+ custom_intro="""
815
+ The M2M100 Model with a language modeling head. Can be used for summarization.
816
+ """
817
+ )
818
+ class M2M100ForConditionalGeneration(M2M100PreTrainedModel, GenerationMixin):
819
+ base_model_prefix = "model"
820
+ _tied_weights_keys = {"lm_head.weight": "model.shared.weight"}
821
+
822
+ def __init__(self, config: M2M100Config):
823
+ super().__init__(config)
824
+ self.model = M2M100Model(config)
825
+ self.lm_head = nn.Linear(config.d_model, self.model.shared.num_embeddings, bias=False)
826
+
827
+ # Initialize weights and apply final processing
828
+ self.post_init()
829
+
830
+ @merge_with_config_defaults
831
+ @capture_outputs
832
+ @auto_docstring
833
+ def forward(
834
+ self,
835
+ input_ids: torch.LongTensor | None = None,
836
+ attention_mask: torch.Tensor | None = None,
837
+ decoder_input_ids: torch.LongTensor | None = None,
838
+ decoder_attention_mask: torch.LongTensor | None = None,
839
+ encoder_outputs: tuple[tuple[torch.FloatTensor]] | None = None,
840
+ past_key_values: Cache | None = None,
841
+ inputs_embeds: torch.FloatTensor | None = None,
842
+ decoder_inputs_embeds: torch.FloatTensor | None = None,
843
+ labels: torch.LongTensor | None = None,
844
+ use_cache: bool | None = None,
845
+ **kwargs: Unpack[TransformersKwargs],
846
+ ) -> tuple[torch.Tensor] | Seq2SeqLMOutput:
847
+ r"""
848
+ decoder_input_ids (`torch.LongTensor` of shape `(batch_size, target_sequence_length)`, *optional*):
849
+ Indices of decoder input sequence tokens in the vocabulary.
850
+
851
+ Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
852
+ [`PreTrainedTokenizer.__call__`] for details.
853
+
854
+ [What are decoder input IDs?](../glossary#decoder-input-ids)
855
+
856
+ M2M100 uses the `eos_token_id` as the starting token for `decoder_input_ids` generation. If
857
+ `past_key_values` is used, optionally only the last `decoder_input_ids` have to be input (see
858
+ `past_key_values`).
859
+ decoder_attention_mask (`torch.LongTensor` of shape `(batch_size, target_sequence_length)`, *optional*):
860
+ Default behavior: generate a tensor that ignores pad tokens in `decoder_input_ids`. Causal mask will also
861
+ be used by default.
862
+ labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
863
+ Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
864
+ config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
865
+ (masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
866
+
867
+ Example Translation:
868
+
869
+ ```python
870
+ >>> from transformers import AutoTokenizer, M2M100ForConditionalGeneration
871
+
872
+ >>> model = M2M100ForConditionalGeneration.from_pretrained("facebook/m2m100_418M")
873
+ >>> tokenizer = AutoTokenizer.from_pretrained("facebook/m2m100_418M")
874
+
875
+ >>> text_to_translate = "Life is like a box of chocolates"
876
+ >>> model_inputs = tokenizer(text_to_translate, return_tensors="pt")
877
+
878
+ >>> # translate to French
879
+ >>> gen_tokens = model.generate(**model_inputs, forced_bos_token_id=tokenizer.get_lang_id("fr"))
880
+ >>> print(tokenizer.batch_decode(gen_tokens, skip_special_tokens=True))
881
+ ```
882
+ """
883
+ if labels is not None:
884
+ if decoder_input_ids is None:
885
+ decoder_input_ids = shift_tokens_right(
886
+ labels, self.config.pad_token_id, self.config.decoder_start_token_id
887
+ )
888
+
889
+ outputs = self.model(
890
+ input_ids,
891
+ attention_mask=attention_mask,
892
+ decoder_input_ids=decoder_input_ids,
893
+ encoder_outputs=encoder_outputs,
894
+ decoder_attention_mask=decoder_attention_mask,
895
+ past_key_values=past_key_values,
896
+ inputs_embeds=inputs_embeds,
897
+ decoder_inputs_embeds=decoder_inputs_embeds,
898
+ use_cache=use_cache,
899
+ **kwargs,
900
+ )
901
+ lm_logits = self.lm_head(outputs.last_hidden_state)
902
+
903
+ masked_lm_loss = None
904
+ if labels is not None:
905
+ # move labels to the correct device to enable PP
906
+ labels = labels.to(lm_logits.device)
907
+ loss_fct = CrossEntropyLoss()
908
+ masked_lm_loss = loss_fct(lm_logits.view(-1, self.config.vocab_size), labels.view(-1))
909
+
910
+ return Seq2SeqLMOutput(
911
+ loss=masked_lm_loss,
912
+ logits=lm_logits,
913
+ past_key_values=outputs.past_key_values,
914
+ decoder_hidden_states=outputs.decoder_hidden_states,
915
+ decoder_attentions=outputs.decoder_attentions,
916
+ cross_attentions=outputs.cross_attentions,
917
+ encoder_last_hidden_state=outputs.encoder_last_hidden_state,
918
+ encoder_hidden_states=outputs.encoder_hidden_states,
919
+ encoder_attentions=outputs.encoder_attentions,
920
+ )
921
+
922
+
923
+ __all__ = ["M2M100ForConditionalGeneration", "M2M100Model", "M2M100PreTrainedModel"]
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/m2m_100/tokenization_m2m_100.py ADDED
@@ -0,0 +1,384 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2021 The Fairseq Authors and The HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Tokenization classes for M2M100."""
15
+
16
+ import json
17
+ import os
18
+ from pathlib import Path
19
+ from shutil import copyfile
20
+ from typing import Any
21
+
22
+ import sentencepiece
23
+
24
+ from ...tokenization_python import BatchEncoding, PreTrainedTokenizer
25
+ from ...utils import logging
26
+ from ...utils.import_utils import requires
27
+
28
+
29
+ logger = logging.get_logger(__name__)
30
+
31
+ SPIECE_UNDERLINE = "▁"
32
+
33
+ VOCAB_FILES_NAMES = {
34
+ "vocab_file": "vocab.json",
35
+ "spm_file": "sentencepiece.bpe.model",
36
+ "tokenizer_config_file": "tokenizer_config.json",
37
+ }
38
+
39
+
40
+ # fmt: off
41
+ FAIRSEQ_LANGUAGE_CODES = {
42
+ "m2m100": ["af", "am", "ar", "ast", "az", "ba", "be", "bg", "bn", "br", "bs", "ca", "ceb", "cs", "cy", "da", "de", "el", "en", "es", "et", "fa", "ff", "fi", "fr", "fy", "ga", "gd", "gl", "gu", "ha", "he", "hi", "hr", "ht", "hu", "hy", "id", "ig", "ilo", "is", "it", "ja", "jv", "ka", "kk", "km", "kn", "ko", "lb", "lg", "ln", "lo", "lt", "lv", "mg", "mk", "ml", "mn", "mr", "ms", "my", "ne", "nl", "no", "ns", "oc", "or", "pa", "pl", "ps", "pt", "ro", "ru", "sd", "si", "sk", "sl", "so", "sq", "sr", "ss", "su", "sv", "sw", "ta", "th", "tl", "tn", "tr", "uk", "ur", "uz", "vi", "wo", "xh", "yi", "yo", "zh", "zu"],
43
+ "wmt21": ['en', 'ha', 'is', 'ja', 'cs', 'ru', 'zh', 'de']
44
+ }
45
+ # fmt: on
46
+
47
+
48
+ @requires(backends=("sentencepiece",))
49
+ class M2M100Tokenizer(PreTrainedTokenizer):
50
+ """
51
+ Construct an M2M100 tokenizer. Based on [SentencePiece](https://github.com/google/sentencepiece).
52
+
53
+ This tokenizer inherits from [`PreTrainedTokenizer`] which contains most of the main methods. Users should refer to
54
+ this superclass for more information regarding those methods.
55
+
56
+ Args:
57
+ vocab_file (`str`):
58
+ Path to the vocabulary file.
59
+ spm_file (`str`):
60
+ Path to [SentencePiece](https://github.com/google/sentencepiece) file (generally has a .spm extension) that
61
+ contains the vocabulary.
62
+ src_lang (`str`, *optional*):
63
+ A string representing the source language.
64
+ tgt_lang (`str`, *optional*):
65
+ A string representing the target language.
66
+ eos_token (`str`, *optional*, defaults to `"</s>"`):
67
+ The end of sequence token.
68
+ sep_token (`str`, *optional*, defaults to `"</s>"`):
69
+ The separator token, which is used when building a sequence from multiple sequences, e.g. two sequences for
70
+ sequence classification or for a text and a question for question answering. It is also used as the last
71
+ token of a sequence built with special tokens.
72
+ unk_token (`str`, *optional*, defaults to `"<unk>"`):
73
+ The unknown token. A token that is not in the vocabulary cannot be converted to an ID and is set to be this
74
+ token instead.
75
+ pad_token (`str`, *optional*, defaults to `"<pad>"`):
76
+ The token used for padding, for example when batching sequences of different lengths.
77
+ language_codes (`str`, *optional*, defaults to `"m2m100"`):
78
+ What language codes to use. Should be one of `"m2m100"` or `"wmt21"`.
79
+ sp_model_kwargs (`dict`, *optional*):
80
+ Will be passed to the `SentencePieceProcessor.__init__()` method. The [Python wrapper for
81
+ SentencePiece](https://github.com/google/sentencepiece/tree/master/python) can be used, among other things,
82
+ to set:
83
+
84
+ - `enable_sampling`: Enable subword regularization.
85
+ - `nbest_size`: Sampling parameters for unigram. Invalid for BPE-Dropout.
86
+
87
+ - `nbest_size = {0,1}`: No sampling is performed.
88
+ - `nbest_size > 1`: samples from the nbest_size results.
89
+ - `nbest_size < 0`: assuming that nbest_size is infinite and samples from the all hypothesis (lattice)
90
+ using forward-filtering-and-backward-sampling algorithm.
91
+
92
+ - `alpha`: Smoothing parameter for unigram sampling, and dropout probability of merge operations for
93
+ BPE-dropout.
94
+
95
+ Examples:
96
+
97
+ ```python
98
+ >>> from transformers import M2M100ForConditionalGeneration, M2M100Tokenizer
99
+
100
+ >>> model = M2M100ForConditionalGeneration.from_pretrained("facebook/m2m100_418M")
101
+ >>> tokenizer = M2M100Tokenizer.from_pretrained("facebook/m2m100_418M", src_lang="en", tgt_lang="ro")
102
+ >>> src_text = " UN Chief Says There Is No Military Solution in Syria"
103
+ >>> tgt_text = "Şeful ONU declară că nu există o soluţie militară în Siria"
104
+ >>> model_inputs = tokenizer(src_text, text_target=tgt_text, return_tensors="pt")
105
+ >>> outputs = model(**model_inputs) # should work
106
+ ```"""
107
+
108
+ vocab_files_names = VOCAB_FILES_NAMES
109
+ model_input_names = ["input_ids", "attention_mask"]
110
+
111
+ prefix_tokens: list[int] = []
112
+ suffix_tokens: list[int] = []
113
+
114
+ def __init__(
115
+ self,
116
+ vocab_file,
117
+ spm_file,
118
+ src_lang=None,
119
+ tgt_lang=None,
120
+ bos_token="<s>",
121
+ eos_token="</s>",
122
+ sep_token="</s>",
123
+ pad_token="<pad>",
124
+ unk_token="<unk>",
125
+ language_codes="m2m100",
126
+ sp_model_kwargs: dict[str, Any] | None = None,
127
+ num_madeup_words=8,
128
+ **kwargs,
129
+ ) -> None:
130
+ self.sp_model_kwargs = {} if sp_model_kwargs is None else sp_model_kwargs
131
+
132
+ self.language_codes = language_codes
133
+ fairseq_language_code = FAIRSEQ_LANGUAGE_CODES[language_codes]
134
+ self.lang_code_to_token = {lang_code: f"__{lang_code}__" for lang_code in fairseq_language_code}
135
+
136
+ additional_special_tokens = kwargs.pop("additional_special_tokens", [])
137
+ for lang_code in fairseq_language_code:
138
+ token = self.get_lang_token(lang_code)
139
+ if token not in additional_special_tokens and lang_code not in str(token) not in self.added_tokens_encoder:
140
+ additional_special_tokens.append(token)
141
+
142
+ self.vocab_file = vocab_file
143
+ self.encoder = load_json(vocab_file)
144
+ self.decoder = {v: k for k, v in self.encoder.items()}
145
+ self.spm_file = spm_file
146
+ self.sp_model = load_spm(spm_file, self.sp_model_kwargs)
147
+
148
+ self.encoder_size = len(self.encoder)
149
+
150
+ self.lang_token_to_id = {
151
+ self.get_lang_token(lang_code): self.encoder_size + i for i, lang_code in enumerate(fairseq_language_code)
152
+ }
153
+ self.lang_code_to_id = {lang_code: self.encoder_size + i for i, lang_code in enumerate(fairseq_language_code)}
154
+ self.id_to_lang_token = {v: k for k, v in self.lang_token_to_id.items()}
155
+
156
+ self._src_lang = src_lang if src_lang is not None else "en"
157
+ self.tgt_lang = tgt_lang
158
+ self.cur_lang_id = self.get_lang_id(self._src_lang)
159
+
160
+ self.num_madeup_words = num_madeup_words
161
+
162
+ super().__init__(
163
+ src_lang=src_lang,
164
+ tgt_lang=tgt_lang,
165
+ bos_token=bos_token,
166
+ eos_token=eos_token,
167
+ sep_token=sep_token,
168
+ unk_token=unk_token,
169
+ pad_token=pad_token,
170
+ language_codes=language_codes,
171
+ sp_model_kwargs=self.sp_model_kwargs,
172
+ additional_special_tokens=additional_special_tokens,
173
+ num_madeup_words=num_madeup_words,
174
+ **kwargs,
175
+ )
176
+ self.set_src_lang_special_tokens(self._src_lang)
177
+
178
+ @property
179
+ def vocab_size(self) -> int:
180
+ return len(self.encoder)
181
+
182
+ def get_vocab(self) -> dict:
183
+ vocab = {self.convert_ids_to_tokens(i): i for i in range(self.vocab_size)}
184
+ vocab.update(self.added_tokens_encoder)
185
+ return vocab
186
+
187
+ @property
188
+ def src_lang(self) -> str:
189
+ return self._src_lang
190
+
191
+ @src_lang.setter
192
+ def src_lang(self, new_src_lang: str) -> None:
193
+ self._src_lang = new_src_lang
194
+ self.set_src_lang_special_tokens(self._src_lang)
195
+
196
+ def _tokenize(self, text: str) -> list[str]:
197
+ return self.sp_model.encode(text, out_type=str)
198
+
199
+ def _convert_token_to_id(self, token):
200
+ if token in self.lang_token_to_id:
201
+ return self.lang_token_to_id[token]
202
+ return self.encoder.get(token, self.encoder[self.unk_token])
203
+
204
+ def _convert_id_to_token(self, index: int) -> str:
205
+ """Converts an index (integer) in a token (str) using the decoder."""
206
+ if index in self.id_to_lang_token:
207
+ return self.id_to_lang_token[index]
208
+ return self.decoder.get(index, self.unk_token)
209
+
210
+ def convert_tokens_to_string(self, tokens):
211
+ """Converts a sequence of tokens (string) in a single string."""
212
+ current_sub_tokens = []
213
+ out_string = ""
214
+ for token in tokens:
215
+ # make sure that special tokens are not decoded using sentencepiece model
216
+ if token in self.all_special_tokens:
217
+ out_string += self.sp_model.decode(current_sub_tokens) + token
218
+ current_sub_tokens = []
219
+ else:
220
+ current_sub_tokens.append(token)
221
+ out_string += self.sp_model.decode(current_sub_tokens)
222
+ return out_string.strip()
223
+
224
+ def get_special_tokens_mask(
225
+ self, token_ids_0: list[int], token_ids_1: list[int] | None = None, already_has_special_tokens: bool = False
226
+ ) -> list[int]:
227
+ """
228
+ Retrieve sequence ids from a token list that has no special tokens added. This method is called when adding
229
+ special tokens using the tokenizer `prepare_for_model` method.
230
+
231
+ Args:
232
+ token_ids_0 (`list[int]`):
233
+ List of IDs.
234
+ token_ids_1 (`list[int]`, *optional*):
235
+ Optional second list of IDs for sequence pairs.
236
+ already_has_special_tokens (`bool`, *optional*, defaults to `False`):
237
+ Whether or not the token list is already formatted with special tokens for the model.
238
+
239
+ Returns:
240
+ `list[int]`: A list of integers in the range [0, 1]: 1 for a special token, 0 for a sequence token.
241
+ """
242
+
243
+ if already_has_special_tokens:
244
+ return super().get_special_tokens_mask(
245
+ token_ids_0=token_ids_0, token_ids_1=token_ids_1, already_has_special_tokens=True
246
+ )
247
+
248
+ prefix_ones = [1] * len(self.prefix_tokens)
249
+ suffix_ones = [1] * len(self.suffix_tokens)
250
+ if token_ids_1 is None:
251
+ return prefix_ones + ([0] * len(token_ids_0)) + suffix_ones
252
+ return prefix_ones + ([0] * len(token_ids_0)) + ([0] * len(token_ids_1)) + suffix_ones
253
+
254
+ def build_inputs_with_special_tokens(
255
+ self, token_ids_0: list[int], token_ids_1: list[int] | None = None
256
+ ) -> list[int]:
257
+ """
258
+ Build model inputs from a sequence or a pair of sequence for sequence classification tasks by concatenating and
259
+ adding special tokens. An MBART sequence has the following format, where `X` represents the sequence:
260
+
261
+ - `input_ids` (for encoder) `X [eos, src_lang_code]`
262
+ - `decoder_input_ids`: (for decoder) `X [eos, tgt_lang_code]`
263
+
264
+ BOS is never used. Pairs of sequences are not the expected use case, but they will be handled without a
265
+ separator.
266
+
267
+ Args:
268
+ token_ids_0 (`list[int]`):
269
+ List of IDs to which the special tokens will be added.
270
+ token_ids_1 (`list[int]`, *optional*):
271
+ Optional second list of IDs for sequence pairs.
272
+
273
+ Returns:
274
+ `list[int]`: List of [input IDs](../glossary#input-ids) with the appropriate special tokens.
275
+ """
276
+ if token_ids_1 is None:
277
+ return self.prefix_tokens + token_ids_0 + self.suffix_tokens
278
+ # We don't expect to process pairs, but leave the pair logic for API consistency
279
+ return self.prefix_tokens + token_ids_0 + token_ids_1 + self.suffix_tokens
280
+
281
+ def __getstate__(self) -> dict:
282
+ state = self.__dict__.copy()
283
+ state["sp_model"] = None
284
+ return state
285
+
286
+ def __setstate__(self, d: dict) -> None:
287
+ self.__dict__ = d
288
+
289
+ # for backward compatibility
290
+ if not hasattr(self, "sp_model_kwargs"):
291
+ self.sp_model_kwargs = {}
292
+
293
+ self.sp_model = load_spm(self.spm_file, self.sp_model_kwargs)
294
+
295
+ def save_vocabulary(self, save_directory: str, filename_prefix: str | None = None) -> tuple[str]:
296
+ save_dir = Path(save_directory)
297
+ if not save_dir.is_dir():
298
+ raise OSError(f"{save_directory} should be a directory")
299
+ vocab_save_path = save_dir / (
300
+ (filename_prefix + "-" if filename_prefix else "") + self.vocab_files_names["vocab_file"]
301
+ )
302
+ spm_save_path = save_dir / (
303
+ (filename_prefix + "-" if filename_prefix else "") + self.vocab_files_names["spm_file"]
304
+ )
305
+
306
+ save_json(self.encoder, vocab_save_path)
307
+
308
+ if os.path.abspath(self.spm_file) != os.path.abspath(spm_save_path) and os.path.isfile(self.spm_file):
309
+ copyfile(self.spm_file, spm_save_path)
310
+ elif not os.path.isfile(self.spm_file):
311
+ with open(spm_save_path, "wb") as fi:
312
+ content_spiece_model = self.sp_model.serialized_model_proto()
313
+ fi.write(content_spiece_model)
314
+
315
+ return (str(vocab_save_path), str(spm_save_path))
316
+
317
+ def prepare_seq2seq_batch(
318
+ self,
319
+ src_texts: list[str],
320
+ src_lang: str = "en",
321
+ tgt_texts: list[str] | None = None,
322
+ tgt_lang: str = "ro",
323
+ **kwargs,
324
+ ) -> BatchEncoding:
325
+ self.src_lang = src_lang
326
+ self.tgt_lang = tgt_lang
327
+ self.set_src_lang_special_tokens(self.src_lang)
328
+ return super().prepare_seq2seq_batch(src_texts, tgt_texts, **kwargs)
329
+
330
+ def _build_translation_inputs(self, raw_inputs, src_lang: str | None, tgt_lang: str | None, **extra_kwargs):
331
+ """Used by translation pipeline, to prepare inputs for the generate function"""
332
+ if src_lang is None or tgt_lang is None:
333
+ raise ValueError("Translation requires a `src_lang` and a `tgt_lang` for this model")
334
+ self.src_lang = src_lang
335
+ inputs = self(raw_inputs, add_special_tokens=True, **extra_kwargs)
336
+ tgt_lang_id = self.get_lang_id(tgt_lang)
337
+ inputs["forced_bos_token_id"] = tgt_lang_id
338
+ return inputs
339
+
340
+ def _switch_to_input_mode(self):
341
+ self.set_src_lang_special_tokens(self.src_lang)
342
+
343
+ def _switch_to_target_mode(self):
344
+ self.set_tgt_lang_special_tokens(self.tgt_lang)
345
+
346
+ def set_src_lang_special_tokens(self, src_lang: str) -> None:
347
+ """Reset the special tokens to the source lang setting. No prefix and suffix=[eos, src_lang_code]."""
348
+ lang_token = self.get_lang_token(src_lang)
349
+ self.cur_lang_id = self.lang_token_to_id[lang_token]
350
+ self.prefix_tokens = [self.cur_lang_id]
351
+ self.suffix_tokens = [self.eos_token_id]
352
+
353
+ def set_tgt_lang_special_tokens(self, tgt_lang: str) -> None:
354
+ """Reset the special tokens to the target language setting. No prefix and suffix=[eos, tgt_lang_code]."""
355
+ lang_token = self.get_lang_token(tgt_lang)
356
+ self.cur_lang_id = self.lang_token_to_id[lang_token]
357
+ self.prefix_tokens = [self.cur_lang_id]
358
+ self.suffix_tokens = [self.eos_token_id]
359
+
360
+ def get_lang_token(self, lang: str) -> str:
361
+ return self.lang_code_to_token[lang]
362
+
363
+ def get_lang_id(self, lang: str) -> int:
364
+ lang_token = self.get_lang_token(lang)
365
+ return self.lang_token_to_id[lang_token]
366
+
367
+
368
+ def load_spm(path: str, sp_model_kwargs: dict[str, Any]) -> sentencepiece.SentencePieceProcessor:
369
+ spm = sentencepiece.SentencePieceProcessor(**sp_model_kwargs)
370
+ spm.Load(str(path))
371
+ return spm
372
+
373
+
374
+ def load_json(path: str) -> dict | list:
375
+ with open(path, "r") as f:
376
+ return json.load(f)
377
+
378
+
379
+ def save_json(data, path: str) -> None:
380
+ with open(path, "w") as f:
381
+ json.dump(data, f, indent=2)
382
+
383
+
384
+ __all__ = ["M2M100Tokenizer"]
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/nanochat/__init__.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import TYPE_CHECKING
2
+
3
+ from ...utils import _LazyModule
4
+ from ...utils.import_utils import define_import_structure
5
+
6
+
7
+ if TYPE_CHECKING:
8
+ from .configuration_nanochat import *
9
+ from .modeling_nanochat import *
10
+ else:
11
+ import sys
12
+
13
+ _file = globals()["__file__"]
14
+ sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/nanochat/configuration_nanochat.py ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 The HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ from huggingface_hub.dataclasses import strict
17
+
18
+ from ...configuration_utils import PreTrainedConfig
19
+ from ...modeling_rope_utils import RopeParameters
20
+ from ...utils import auto_docstring
21
+
22
+
23
+ @auto_docstring(checkpoint="karpathy/nanochat-d32")
24
+ @strict
25
+ class NanoChatConfig(PreTrainedConfig):
26
+ r"""
27
+ Example:
28
+
29
+ ```python
30
+ >>> from transformers import NanoChatModel, NanoChatConfig
31
+
32
+ >>> # Initializing a NanoChat style configuration
33
+ >>> configuration = NanoChatConfig()
34
+
35
+ >>> # Initializing a model from the NanoChat style configuration
36
+ >>> model = NanoChatModel(configuration)
37
+
38
+ >>> # Accessing the model configuration
39
+ >>> configuration = model.config
40
+ ```"""
41
+
42
+ model_type = "nanochat"
43
+ keys_to_ignore_at_inference = ["past_key_values"]
44
+
45
+ base_model_tp_plan = {
46
+ "layers.*.self_attn.q_proj": "colwise",
47
+ "layers.*.self_attn.k_proj": "colwise",
48
+ "layers.*.self_attn.v_proj": "colwise",
49
+ "layers.*.self_attn.o_proj": "rowwise",
50
+ "layers.*.mlp.fc1": "colwise",
51
+ "layers.*.mlp.fc2": "rowwise",
52
+ }
53
+
54
+ vocab_size: int = 50304
55
+ hidden_size: int = 768
56
+ intermediate_size: int = 8192
57
+ num_hidden_layers: int = 12
58
+ num_attention_heads: int = 6
59
+ num_key_value_heads: int | None = None
60
+ max_position_embeddings: int = 2048
61
+ hidden_act: str = "relu2"
62
+ attention_dropout: float | int = 0.0
63
+ rms_norm_eps: float = 1e-6
64
+ initializer_range: float = 0.02
65
+ rope_parameters: RopeParameters | dict | None = None
66
+ use_cache: bool = True
67
+ final_logit_softcapping: float | None = 15.0
68
+ attention_bias: bool = False
69
+ bos_token_id: int | None = 0
70
+ eos_token_id: int | list[int] | None = 1
71
+ pad_token_id: int | None = 1
72
+ tie_word_embeddings: bool = False
73
+
74
+ def __post_init__(self, **kwargs):
75
+ if self.num_key_value_heads is None:
76
+ self.num_key_value_heads = self.num_attention_heads
77
+
78
+ super().__post_init__(**kwargs)
79
+
80
+
81
+ __all__ = ["NanoChatConfig"]
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/nanochat/modeling_nanochat.py ADDED
@@ -0,0 +1,518 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/nanochat/modular_nanochat.py.
3
+ # Do NOT edit this file manually as any edits will be overwritten by the generation of
4
+ # the file from the modular. If any change should be done, please apply the change to the
5
+ # modular_nanochat.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2025 The HuggingFace Inc. team. All rights reserved.
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+
21
+ import math
22
+ from collections.abc import Callable
23
+ from typing import Optional
24
+
25
+ import torch
26
+ import torch.nn as nn
27
+
28
+ from ... import initialization as init
29
+ from ...activations import ACT2FN
30
+ from ...cache_utils import Cache, DynamicCache
31
+ from ...generation import GenerationMixin
32
+ from ...integrations import use_kernel_func_from_hub, use_kernelized_func
33
+ from ...masking_utils import create_causal_mask
34
+ from ...modeling_layers import GradientCheckpointingLayer
35
+ from ...modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast
36
+ from ...modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update
37
+ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
38
+ from ...processing_utils import Unpack
39
+ from ...utils import TransformersKwargs, auto_docstring
40
+ from ...utils.generic import can_return_tuple, maybe_autocast, merge_with_config_defaults
41
+ from ...utils.output_capturing import capture_outputs
42
+ from .configuration_nanochat import NanoChatConfig
43
+
44
+
45
+ class NanoChatRMSNorm(torch.nn.Module):
46
+ def __init__(self, eps: float = 1e-6):
47
+ super().__init__()
48
+ self.eps = eps
49
+
50
+ def _norm(self, x):
51
+ return x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + self.eps)
52
+
53
+ def forward(self, x):
54
+ return self._norm(x.float()).type_as(x)
55
+
56
+ def extra_repr(self):
57
+ return f"eps={self.eps}"
58
+
59
+
60
+ class NanoChatRotaryEmbedding(nn.Module):
61
+ inv_freq: torch.Tensor # fix linting for `register_buffer`
62
+
63
+ def __init__(self, config: NanoChatConfig, device=None):
64
+ super().__init__()
65
+ self.max_seq_len_cached = config.max_position_embeddings
66
+ self.original_max_seq_len = config.max_position_embeddings
67
+
68
+ self.config = config
69
+
70
+ self.rope_type = self.config.rope_parameters["rope_type"]
71
+ rope_init_fn: Callable = self.compute_default_rope_parameters
72
+ if self.rope_type != "default":
73
+ rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type]
74
+ inv_freq, self.attention_scaling = rope_init_fn(self.config, device)
75
+
76
+ self.register_buffer("inv_freq", inv_freq, persistent=False)
77
+ self.register_buffer("original_inv_freq", inv_freq.clone(), persistent=False)
78
+
79
+ @staticmethod
80
+ def compute_default_rope_parameters(
81
+ config: NanoChatConfig | None = None,
82
+ device: Optional["torch.device"] = None,
83
+ seq_len: int | None = None,
84
+ ) -> tuple["torch.Tensor", float]:
85
+ """
86
+ Computes the inverse frequencies according to the original RoPE implementation
87
+ Args:
88
+ config ([`~transformers.PreTrainedConfig`]):
89
+ The model configuration.
90
+ device (`torch.device`):
91
+ The device to use for initialization of the inverse frequencies.
92
+ seq_len (`int`, *optional*):
93
+ The current sequence length. Unused for this type of RoPE.
94
+ Returns:
95
+ Tuple of (`torch.Tensor`, `float`), containing the inverse frequencies for the RoPE embeddings and the
96
+ post-processing scaling factor applied to the computed cos/sin (unused in this type of RoPE).
97
+ """
98
+ base = config.rope_parameters["rope_theta"]
99
+ dim = getattr(config, "head_dim", None) or config.hidden_size // config.num_attention_heads
100
+
101
+ attention_factor = 1.0 # Unused in this type of RoPE
102
+
103
+ # Compute the inverse frequencies
104
+ inv_freq = 1.0 / (
105
+ base ** (torch.arange(0, dim, 2, dtype=torch.int64).to(device=device, dtype=torch.float) / dim)
106
+ )
107
+ return inv_freq, attention_factor
108
+
109
+ @torch.no_grad()
110
+ @dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope)
111
+ def forward(self, x, position_ids):
112
+ inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1).to(x.device)
113
+ position_ids_expanded = position_ids[:, None, :].float()
114
+
115
+ device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu"
116
+ with maybe_autocast(device_type=device_type, enabled=False): # Force float32
117
+ freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2)
118
+ emb = torch.cat((freqs, freqs), dim=-1)
119
+ cos = emb.cos() * self.attention_scaling
120
+ sin = emb.sin() * self.attention_scaling
121
+
122
+ return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype)
123
+
124
+
125
+ @use_kernel_func_from_hub("rotary_pos_emb")
126
+ def apply_rotary_pos_emb(q, k, cos, sin, unsqueeze_dim=1):
127
+ """Applies Rotary Position Embedding to the query and key tensors.
128
+
129
+ Args:
130
+ q (`torch.Tensor`): The query tensor.
131
+ k (`torch.Tensor`): The key tensor.
132
+ cos (`torch.Tensor`): The cosine part of the rotary embedding.
133
+ sin (`torch.Tensor`): The sine part of the rotary embedding.
134
+ unsqueeze_dim (`int`, *optional*, defaults to 1):
135
+ The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and
136
+ sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note
137
+ that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and
138
+ k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes
139
+ cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have
140
+ the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2.
141
+ Returns:
142
+ `tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding.
143
+ """
144
+ cos = cos.unsqueeze(unsqueeze_dim)
145
+ sin = sin.unsqueeze(unsqueeze_dim)
146
+ q_embed = (q * cos) + (rotate_half(q) * sin)
147
+ k_embed = (k * cos) + (rotate_half(k) * sin)
148
+ return q_embed, k_embed
149
+
150
+
151
+ def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
152
+ """
153
+ This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch,
154
+ num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim)
155
+ """
156
+ batch, num_key_value_heads, slen, head_dim = hidden_states.shape
157
+ if n_rep == 1:
158
+ return hidden_states
159
+ hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim)
160
+ return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)
161
+
162
+
163
+ def eager_attention_forward(
164
+ module: nn.Module,
165
+ query: torch.Tensor,
166
+ key: torch.Tensor,
167
+ value: torch.Tensor,
168
+ attention_mask: torch.Tensor | None,
169
+ scaling: float,
170
+ dropout: float = 0.0,
171
+ **kwargs: Unpack[TransformersKwargs],
172
+ ):
173
+ key_states = repeat_kv(key, module.num_key_value_groups)
174
+ value_states = repeat_kv(value, module.num_key_value_groups)
175
+
176
+ attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling
177
+ if attention_mask is not None:
178
+ attn_weights = attn_weights + attention_mask
179
+
180
+ attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype)
181
+ attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
182
+ attn_output = torch.matmul(attn_weights, value_states)
183
+ attn_output = attn_output.transpose(1, 2).contiguous()
184
+
185
+ return attn_output, attn_weights
186
+
187
+
188
+ def rotate_half(x):
189
+ """Rotates half the hidden dims of the input with flipped signs for NanoChat."""
190
+ x1 = x[..., : x.shape[-1] // 2]
191
+ x2 = x[..., x.shape[-1] // 2 :]
192
+ return torch.cat((x2, -x1), dim=-1)
193
+
194
+
195
+ @use_kernelized_func(apply_rotary_pos_emb)
196
+ class NanoChatAttention(nn.Module):
197
+ """Multi-headed attention from 'Attention Is All You Need' paper"""
198
+
199
+ def __init__(self, config: NanoChatConfig, layer_idx: int):
200
+ super().__init__()
201
+ self.config = config
202
+ self.layer_idx = layer_idx
203
+ self.head_dim = getattr(config, "head_dim", config.hidden_size // config.num_attention_heads)
204
+ self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads
205
+ self.scaling = self.head_dim**-0.5
206
+ self.attention_dropout = config.attention_dropout
207
+ self.is_causal = True
208
+
209
+ self.q_proj = nn.Linear(
210
+ config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias
211
+ )
212
+ self.k_proj = nn.Linear(
213
+ config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
214
+ )
215
+ self.v_proj = nn.Linear(
216
+ config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias
217
+ )
218
+ self.o_proj = nn.Linear(
219
+ config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias
220
+ )
221
+
222
+ self.q_norm = NanoChatRMSNorm(eps=config.rms_norm_eps)
223
+ self.k_norm = NanoChatRMSNorm(eps=config.rms_norm_eps)
224
+
225
+ def forward(
226
+ self,
227
+ hidden_states: torch.Tensor,
228
+ position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
229
+ attention_mask: torch.Tensor | None = None,
230
+ past_key_values: Cache | None = None,
231
+ **kwargs: Unpack[TransformersKwargs],
232
+ ) -> tuple[torch.Tensor, torch.Tensor | None]:
233
+ input_shape = hidden_states.shape[:-1]
234
+ hidden_shape = (*input_shape, -1, self.head_dim)
235
+
236
+ query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2)
237
+ key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2)
238
+ value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2)
239
+
240
+ cos, sin = position_embeddings
241
+ query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
242
+
243
+ # RoPE -> Norm (instead of usual Norm -> RoPE)
244
+ query_states = self.q_norm(query_states)
245
+ key_states = self.k_norm(key_states)
246
+
247
+ if past_key_values is not None:
248
+ key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
249
+
250
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
251
+ self.config._attn_implementation, eager_attention_forward
252
+ )
253
+
254
+ attn_output, attn_weights = attention_interface(
255
+ self,
256
+ query_states,
257
+ key_states,
258
+ value_states,
259
+ attention_mask,
260
+ dropout=0.0 if not self.training else self.attention_dropout,
261
+ scaling=self.scaling,
262
+ **kwargs,
263
+ )
264
+
265
+ attn_output = attn_output.reshape(*input_shape, -1).contiguous()
266
+ attn_output = self.o_proj(attn_output)
267
+ return attn_output, attn_weights
268
+
269
+
270
+ class NanoChatMLP(nn.Module):
271
+ def __init__(self, config):
272
+ super().__init__()
273
+ self.config = config
274
+ self.activation_fn = ACT2FN[config.hidden_act]
275
+ self.fc1 = nn.Linear(config.hidden_size, config.intermediate_size, bias=False)
276
+ self.fc2 = nn.Linear(config.intermediate_size, config.hidden_size, bias=False)
277
+
278
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
279
+ hidden_states = self.fc1(hidden_states)
280
+ hidden_states = self.activation_fn(hidden_states)
281
+ hidden_states = self.fc2(hidden_states)
282
+ return hidden_states
283
+
284
+
285
+ class NanoChatDecoderLayer(GradientCheckpointingLayer):
286
+ def __init__(self, config: NanoChatConfig, layer_idx: int):
287
+ super().__init__()
288
+ self.hidden_size = config.hidden_size
289
+
290
+ self.self_attn = NanoChatAttention(config=config, layer_idx=layer_idx)
291
+
292
+ self.mlp = NanoChatMLP(config)
293
+
294
+ self.input_layernorm = NanoChatRMSNorm(eps=config.rms_norm_eps)
295
+ self.post_attention_layernorm = NanoChatRMSNorm(eps=config.rms_norm_eps)
296
+
297
+ def forward(
298
+ self,
299
+ hidden_states: torch.Tensor,
300
+ attention_mask: torch.Tensor | None = None,
301
+ position_ids: torch.LongTensor | None = None,
302
+ past_key_values: Cache | None = None,
303
+ use_cache: bool | None = False,
304
+ position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
305
+ **kwargs: Unpack[TransformersKwargs],
306
+ ) -> torch.Tensor:
307
+ residual = hidden_states
308
+ hidden_states = self.input_layernorm(hidden_states)
309
+ # Self Attention
310
+ hidden_states, _ = self.self_attn(
311
+ hidden_states=hidden_states,
312
+ attention_mask=attention_mask,
313
+ position_ids=position_ids,
314
+ past_key_values=past_key_values,
315
+ use_cache=use_cache,
316
+ position_embeddings=position_embeddings,
317
+ **kwargs,
318
+ )
319
+ hidden_states = residual + hidden_states
320
+
321
+ # Fully Connected
322
+ residual = hidden_states
323
+ hidden_states = self.post_attention_layernorm(hidden_states)
324
+ hidden_states = self.mlp(hidden_states)
325
+ hidden_states = residual + hidden_states
326
+ return hidden_states
327
+
328
+
329
+ @auto_docstring
330
+ class NanoChatPreTrainedModel(PreTrainedModel):
331
+ config: NanoChatConfig
332
+ base_model_prefix = "model"
333
+ supports_gradient_checkpointing = True
334
+ _no_split_modules = ["NanoChatDecoderLayer"]
335
+ _skip_keys_device_placement = ["past_key_values"]
336
+ _supports_flash_attn = True
337
+ _supports_sdpa = True
338
+ _supports_flex_attn = True
339
+
340
+ _can_compile_fullgraph = True
341
+ _supports_attention_backend = True
342
+ _can_record_outputs = {
343
+ "hidden_states": NanoChatDecoderLayer,
344
+ "attentions": NanoChatAttention,
345
+ }
346
+
347
+ def _init_weights(self, module: nn.Module) -> None:
348
+ super()._init_weights(module)
349
+ if isinstance(module, NanoChatAttention):
350
+ init.normal_(
351
+ module.o_proj.weight,
352
+ mean=0.0,
353
+ std=self.config.initializer_range / math.sqrt(2 * self.config.num_hidden_layers),
354
+ )
355
+
356
+
357
+ @auto_docstring
358
+ class NanoChatModel(NanoChatPreTrainedModel):
359
+ def __init__(self, config: NanoChatConfig):
360
+ super().__init__(config)
361
+ self.padding_idx = config.pad_token_id
362
+ self.vocab_size = config.vocab_size
363
+
364
+ self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx)
365
+ self.layers = nn.ModuleList(
366
+ [NanoChatDecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
367
+ )
368
+
369
+ self.norm = NanoChatRMSNorm(eps=config.rms_norm_eps)
370
+ self.rotary_emb = NanoChatRotaryEmbedding(config=config)
371
+ self.gradient_checkpointing = False
372
+
373
+ # Initialize weights and apply final processing
374
+ self.post_init()
375
+
376
+ @merge_with_config_defaults
377
+ @capture_outputs
378
+ @auto_docstring
379
+ def forward(
380
+ self,
381
+ input_ids: torch.LongTensor | None = None,
382
+ attention_mask: torch.Tensor | None = None,
383
+ position_ids: torch.LongTensor | None = None,
384
+ past_key_values: Cache | None = None,
385
+ inputs_embeds: torch.FloatTensor | None = None,
386
+ use_cache: bool | None = None,
387
+ **kwargs: Unpack[TransformersKwargs],
388
+ ) -> BaseModelOutputWithPast:
389
+ if (input_ids is None) ^ (inputs_embeds is not None):
390
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
391
+
392
+ if inputs_embeds is None:
393
+ inputs_embeds: torch.Tensor = self.embed_tokens(input_ids)
394
+
395
+ if use_cache and past_key_values is None:
396
+ past_key_values = DynamicCache(config=self.config)
397
+
398
+ if position_ids is None:
399
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
400
+ position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens
401
+ position_ids = position_ids.unsqueeze(0)
402
+
403
+ causal_mask = create_causal_mask(
404
+ config=self.config,
405
+ inputs_embeds=inputs_embeds,
406
+ attention_mask=attention_mask,
407
+ past_key_values=past_key_values,
408
+ position_ids=position_ids,
409
+ )
410
+
411
+ hidden_states = inputs_embeds
412
+ position_embeddings = self.rotary_emb(hidden_states, position_ids=position_ids)
413
+
414
+ hidden_states = self.norm(hidden_states) # Additional norm before the layers
415
+ for decoder_layer in self.layers[: self.config.num_hidden_layers]:
416
+ hidden_states = decoder_layer(
417
+ hidden_states,
418
+ attention_mask=causal_mask,
419
+ position_embeddings=position_embeddings,
420
+ position_ids=position_ids,
421
+ past_key_values=past_key_values,
422
+ **kwargs,
423
+ )
424
+
425
+ hidden_states = self.norm(hidden_states)
426
+ return BaseModelOutputWithPast(
427
+ last_hidden_state=hidden_states,
428
+ past_key_values=past_key_values,
429
+ )
430
+
431
+
432
+ @auto_docstring
433
+ class NanoChatForCausalLM(NanoChatPreTrainedModel, GenerationMixin):
434
+ _tied_weights_keys = {"lm_head.weight": "model.embed_tokens.weight"}
435
+ _tp_plan = {"lm_head": "colwise_gather_output"}
436
+ _pp_plan = {"lm_head": (["hidden_states"], ["logits"])}
437
+
438
+ def __init__(self, config):
439
+ super().__init__(config)
440
+ self.model = NanoChatModel(config)
441
+ self.vocab_size = config.vocab_size
442
+ self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
443
+
444
+ # Initialize weights and apply final processing
445
+ self.post_init()
446
+
447
+ @can_return_tuple
448
+ @auto_docstring
449
+ def forward(
450
+ self,
451
+ input_ids: torch.LongTensor | None = None,
452
+ attention_mask: torch.Tensor | None = None,
453
+ position_ids: torch.LongTensor | None = None,
454
+ past_key_values: Cache | None = None,
455
+ inputs_embeds: torch.FloatTensor | None = None,
456
+ labels: torch.LongTensor | None = None,
457
+ use_cache: bool | None = None,
458
+ logits_to_keep: int | torch.Tensor = 0,
459
+ **kwargs: Unpack[TransformersKwargs],
460
+ ) -> CausalLMOutputWithPast:
461
+ r"""
462
+ Example:
463
+
464
+ ```python
465
+ >>> from transformers import AutoTokenizer, AutoModelForCausalLM
466
+
467
+ >>> model = AutoModelForCausalLM.from_pretrained("karpathy/nanochat-d32")
468
+
469
+ >>> tokenizer = AutoTokenizer.from_pretrained("karpathy/nanochat-d32")
470
+
471
+ >>> conversation = [
472
+ {"role": "user", "content": "What is the capital of France?"},
473
+ ]
474
+
475
+ >>> inputs = tokenizer.apply_chat_template(
476
+ conversation, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt"
477
+ ).to(device)
478
+
479
+ >>> with torch.no_grad():
480
+ >>> outputs = model.generate(**inputs, max_new_tokens=64, do_sample=False)
481
+
482
+ >>> generated_tokens = outputs[0, inputs["input_ids"].shape[1] :]
483
+ >>> output = tokenizer.decode(generated_tokens, skip_special_tokens=True)
484
+ ```"""
485
+ # decoder outputs consists of (dec_features, layer_state, dec_hidden, dec_attn)
486
+ outputs: BaseModelOutputWithPast = self.model(
487
+ input_ids=input_ids,
488
+ attention_mask=attention_mask,
489
+ position_ids=position_ids,
490
+ past_key_values=past_key_values,
491
+ inputs_embeds=inputs_embeds,
492
+ use_cache=use_cache,
493
+ **kwargs,
494
+ )
495
+
496
+ hidden_states = outputs.last_hidden_state
497
+ # Only compute necessary logits, and do not upcast them to float if we are not computing the loss
498
+ slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
499
+ logits = self.lm_head(hidden_states[:, slice_indices, :])
500
+ if self.config.final_logit_softcapping is not None:
501
+ logits = logits / self.config.final_logit_softcapping
502
+ logits = torch.tanh(logits)
503
+ logits = logits * self.config.final_logit_softcapping
504
+
505
+ loss = None
506
+ if labels is not None:
507
+ loss = self.loss_function(logits, labels, self.vocab_size, **kwargs)
508
+
509
+ return CausalLMOutputWithPast(
510
+ loss=loss,
511
+ logits=logits,
512
+ past_key_values=outputs.past_key_values,
513
+ hidden_states=outputs.hidden_states,
514
+ attentions=outputs.attentions,
515
+ )
516
+
517
+
518
+ __all__ = ["NanoChatPreTrainedModel", "NanoChatModel", "NanoChatForCausalLM"]
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/nanochat/modular_nanochat.py ADDED
@@ -0,0 +1,235 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 The HuggingFace Inc. team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import math
16
+ from collections.abc import Callable
17
+
18
+ import torch
19
+ import torch.nn as nn
20
+
21
+ from ... import initialization as init
22
+ from ...cache_utils import Cache, DynamicCache
23
+ from ...masking_utils import create_causal_mask
24
+ from ...modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast
25
+ from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
26
+ from ...processing_utils import Unpack
27
+ from ...utils import TransformersKwargs, auto_docstring
28
+ from ..clip.modeling_clip import CLIPMLP
29
+ from ..gemma2.modeling_gemma2 import Gemma2ForCausalLM
30
+ from ..llama.modeling_llama import (
31
+ LlamaDecoderLayer,
32
+ LlamaModel,
33
+ LlamaPreTrainedModel,
34
+ LlamaRotaryEmbedding,
35
+ apply_rotary_pos_emb,
36
+ eager_attention_forward,
37
+ )
38
+ from ..llama4.modeling_llama4 import Llama4TextL2Norm
39
+ from ..qwen3.modeling_qwen3 import Qwen3Attention
40
+ from .configuration_nanochat import NanoChatConfig
41
+
42
+
43
+ class NanoChatRMSNorm(Llama4TextL2Norm):
44
+ pass
45
+
46
+
47
+ class NanoChatRotaryEmbedding(LlamaRotaryEmbedding):
48
+ pass
49
+
50
+
51
+ def rotate_half(x):
52
+ """Rotates half the hidden dims of the input with flipped signs for NanoChat."""
53
+ x1 = x[..., : x.shape[-1] // 2]
54
+ x2 = x[..., x.shape[-1] // 2 :]
55
+ return torch.cat((x2, -x1), dim=-1)
56
+
57
+
58
+ class NanoChatAttention(Qwen3Attention):
59
+ def __init__(self, config: NanoChatConfig, layer_idx: int):
60
+ super().__init__(config, layer_idx)
61
+ del self.sliding_window
62
+ del self.layer_type
63
+
64
+ self.q_norm = NanoChatRMSNorm(eps=config.rms_norm_eps)
65
+ self.k_norm = NanoChatRMSNorm(eps=config.rms_norm_eps)
66
+
67
+ def forward(
68
+ self,
69
+ hidden_states: torch.Tensor,
70
+ position_embeddings: tuple[torch.Tensor, torch.Tensor] | None = None,
71
+ attention_mask: torch.Tensor | None = None,
72
+ past_key_values: Cache | None = None,
73
+ **kwargs: Unpack[TransformersKwargs],
74
+ ) -> tuple[torch.Tensor, torch.Tensor | None]:
75
+ input_shape = hidden_states.shape[:-1]
76
+ hidden_shape = (*input_shape, -1, self.head_dim)
77
+
78
+ query_states = self.q_proj(hidden_states).view(hidden_shape).transpose(1, 2)
79
+ key_states = self.k_proj(hidden_states).view(hidden_shape).transpose(1, 2)
80
+ value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2)
81
+
82
+ cos, sin = position_embeddings
83
+ query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
84
+
85
+ # RoPE -> Norm (instead of usual Norm -> RoPE)
86
+ query_states = self.q_norm(query_states)
87
+ key_states = self.k_norm(key_states)
88
+
89
+ if past_key_values is not None:
90
+ key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
91
+
92
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
93
+ self.config._attn_implementation, eager_attention_forward
94
+ )
95
+
96
+ attn_output, attn_weights = attention_interface(
97
+ self,
98
+ query_states,
99
+ key_states,
100
+ value_states,
101
+ attention_mask,
102
+ dropout=0.0 if not self.training else self.attention_dropout,
103
+ scaling=self.scaling,
104
+ **kwargs,
105
+ )
106
+
107
+ attn_output = attn_output.reshape(*input_shape, -1).contiguous()
108
+ attn_output = self.o_proj(attn_output)
109
+ return attn_output, attn_weights
110
+
111
+
112
+ class NanoChatMLP(CLIPMLP):
113
+ def __init__(self, config):
114
+ super().__init__(config)
115
+ self.fc1 = nn.Linear(config.hidden_size, config.intermediate_size, bias=False)
116
+ self.fc2 = nn.Linear(config.intermediate_size, config.hidden_size, bias=False)
117
+
118
+
119
+ class NanoChatDecoderLayer(LlamaDecoderLayer):
120
+ def __init__(self, config: NanoChatConfig, layer_idx: int):
121
+ super().__init__()
122
+
123
+ self.input_layernorm = NanoChatRMSNorm(eps=config.rms_norm_eps)
124
+ self.post_attention_layernorm = NanoChatRMSNorm(eps=config.rms_norm_eps)
125
+
126
+
127
+ @auto_docstring
128
+ class NanoChatPreTrainedModel(LlamaPreTrainedModel):
129
+ def _init_weights(self, module: nn.Module) -> None:
130
+ PreTrainedModel._init_weights(self, module)
131
+ if isinstance(module, NanoChatAttention):
132
+ init.normal_(
133
+ module.o_proj.weight,
134
+ mean=0.0,
135
+ std=self.config.initializer_range / math.sqrt(2 * self.config.num_hidden_layers),
136
+ )
137
+
138
+
139
+ @auto_docstring
140
+ class NanoChatModel(LlamaModel):
141
+ def __init__(self, config: NanoChatConfig):
142
+ super().__init__(config)
143
+
144
+ self.norm = NanoChatRMSNorm(eps=config.rms_norm_eps)
145
+
146
+ def forward(
147
+ self,
148
+ input_ids: torch.LongTensor | None = None,
149
+ attention_mask: torch.Tensor | None = None,
150
+ position_ids: torch.LongTensor | None = None,
151
+ past_key_values: Cache | None = None,
152
+ inputs_embeds: torch.FloatTensor | None = None,
153
+ use_cache: bool | None = None,
154
+ **kwargs: Unpack[TransformersKwargs],
155
+ ) -> BaseModelOutputWithPast:
156
+ if (input_ids is None) ^ (inputs_embeds is not None):
157
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
158
+
159
+ if inputs_embeds is None:
160
+ inputs_embeds: torch.Tensor = self.embed_tokens(input_ids)
161
+
162
+ if use_cache and past_key_values is None:
163
+ past_key_values = DynamicCache(config=self.config)
164
+
165
+ if position_ids is None:
166
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
167
+ position_ids = torch.arange(inputs_embeds.shape[1], device=inputs_embeds.device) + past_seen_tokens
168
+ position_ids = position_ids.unsqueeze(0)
169
+
170
+ causal_mask = create_causal_mask(
171
+ config=self.config,
172
+ inputs_embeds=inputs_embeds,
173
+ attention_mask=attention_mask,
174
+ past_key_values=past_key_values,
175
+ position_ids=position_ids,
176
+ )
177
+
178
+ hidden_states = inputs_embeds
179
+ position_embeddings = self.rotary_emb(hidden_states, position_ids=position_ids)
180
+
181
+ hidden_states = self.norm(hidden_states) # Additional norm before the layers
182
+ for decoder_layer in self.layers[: self.config.num_hidden_layers]:
183
+ hidden_states = decoder_layer(
184
+ hidden_states,
185
+ attention_mask=causal_mask,
186
+ position_embeddings=position_embeddings,
187
+ position_ids=position_ids,
188
+ past_key_values=past_key_values,
189
+ **kwargs,
190
+ )
191
+
192
+ hidden_states = self.norm(hidden_states)
193
+ return BaseModelOutputWithPast(
194
+ last_hidden_state=hidden_states,
195
+ past_key_values=past_key_values,
196
+ )
197
+
198
+
199
+ @auto_docstring
200
+ class NanoChatForCausalLM(Gemma2ForCausalLM):
201
+ _tp_plan = {"lm_head": "colwise_gather_output"}
202
+
203
+ def forward(self, **super_kwargs) -> CausalLMOutputWithPast:
204
+ r"""
205
+ Example:
206
+
207
+ ```python
208
+ >>> from transformers import AutoTokenizer, AutoModelForCausalLM
209
+
210
+ >>> model = AutoModelForCausalLM.from_pretrained("karpathy/nanochat-d32")
211
+
212
+ >>> tokenizer = AutoTokenizer.from_pretrained("karpathy/nanochat-d32")
213
+
214
+ >>> conversation = [
215
+ {"role": "user", "content": "What is the capital of France?"},
216
+ ]
217
+
218
+ >>> inputs = tokenizer.apply_chat_template(
219
+ conversation, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt"
220
+ ).to(device)
221
+
222
+ >>> with torch.no_grad():
223
+ >>> outputs = model.generate(**inputs, max_new_tokens=64, do_sample=False)
224
+
225
+ >>> generated_tokens = outputs[0, inputs["input_ids"].shape[1] :]
226
+ >>> output = tokenizer.decode(generated_tokens, skip_special_tokens=True)
227
+ ```"""
228
+ super().forward(**super_kwargs)
229
+
230
+
231
+ __all__ = [
232
+ "NanoChatPreTrainedModel",
233
+ "NanoChatModel",
234
+ "NanoChatForCausalLM",
235
+ ]
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/qwen3_5_moe/__init__.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 The HuggingFace Team. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ from typing import TYPE_CHECKING
15
+
16
+ from ...utils import _LazyModule
17
+ from ...utils.import_utils import define_import_structure
18
+
19
+
20
+ if TYPE_CHECKING:
21
+ from .configuration_qwen3_5_moe import *
22
+ from .modeling_qwen3_5_moe import *
23
+ else:
24
+ import sys
25
+
26
+ _file = globals()["__file__"]
27
+ sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__)
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/qwen3_5_moe/configuration_qwen3_5_moe.py ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/qwen3_5_moe/modular_qwen3_5_moe.py.
3
+ # Do NOT edit this file manually as any edits will be overwritten by the generation of
4
+ # the file from the modular. If any change should be done, please apply the change to the
5
+ # modular_qwen3_5_moe.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2025 The Qwen Team and The HuggingFace Inc. team. All rights reserved.
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+ from huggingface_hub.dataclasses import strict
21
+
22
+ from ...configuration_utils import PreTrainedConfig
23
+ from ...modeling_rope_utils import RopeParameters
24
+ from ...utils import auto_docstring
25
+
26
+
27
+ @auto_docstring(checkpoint="Qwen/Qwen3.5-35B-A3B")
28
+ @strict
29
+ class Qwen3_5MoeTextConfig(PreTrainedConfig):
30
+ r"""
31
+ linear_conv_kernel_dim (`int`, *optional*, defaults to 4):
32
+ Kernel size of the convolution used in linear attention layers.
33
+ linear_key_head_dim (`int`, *optional*, defaults to 128):
34
+ Dimension of each key head in linear attention.
35
+ linear_value_head_dim (`int`, *optional*, defaults to 128):
36
+ Dimension of each value head in linear attention.
37
+ linear_num_key_heads (`int`, *optional*, defaults to 16):
38
+ Number of key heads used in linear attention layers.
39
+ linear_num_value_heads (`int`, *optional*, defaults to 32):
40
+ Number of value heads used in linear attention layers.
41
+
42
+ ```python
43
+ >>> from transformers import Qwen3_5MoeTextModel, Qwen3_5MoeTextConfig
44
+
45
+ >>> # Initializing a Qwen3.5-MoE style configuration
46
+ >>> configuration = Qwen3_5MoeTextConfig()
47
+
48
+ >>> # Initializing a model from the Qwen3.5-35B-A3B style configuration
49
+ >>> model = Qwen3_5MoeTextModel(configuration)
50
+
51
+ >>> # Accessing the model configuration
52
+ >>> configuration = model.config
53
+ ```
54
+ """
55
+
56
+ model_type = "qwen3_5_moe_text"
57
+ keys_to_ignore_at_inference = ["past_key_values"]
58
+
59
+ base_model_tp_plan = {
60
+ "layers.*.self_attn.q_proj": "colwise",
61
+ "layers.*.self_attn.k_proj": "colwise",
62
+ "layers.*.self_attn.v_proj": "colwise",
63
+ "layers.*.self_attn.o_proj": "rowwise",
64
+ "layers.*.self_attn.q_norm": "replicated_with_grad_allreduce",
65
+ "layers.*.self_attn.k_norm": "replicated_with_grad_allreduce",
66
+ "layers.*.mlp.experts.gate_up_proj": "packed_colwise",
67
+ "layers.*.mlp.experts.down_proj": "rowwise",
68
+ "layers.*.mlp.experts": "moe_tp_experts",
69
+ "layers.*.mlp.shared_expert.gate_proj": "colwise",
70
+ "layers.*.mlp.shared_expert.up_proj": "colwise",
71
+ "layers.*.mlp.shared_expert.down_proj": "rowwise",
72
+ }
73
+ base_model_pp_plan = {
74
+ "embed_tokens": (["input_ids"], ["inputs_embeds"]),
75
+ "layers": (["hidden_states", "attention_mask"], ["hidden_states"]),
76
+ "norm": (["hidden_states"], ["hidden_states"]),
77
+ }
78
+
79
+ vocab_size: int = 248320
80
+ hidden_size: int = 2048
81
+ num_hidden_layers: int = 40
82
+ num_attention_heads: int = 16
83
+ num_key_value_heads: int = 2
84
+ hidden_act: str = "silu"
85
+ max_position_embeddings: int = 32768
86
+ initializer_range: float = 0.02
87
+ rms_norm_eps: float = 1e-6
88
+ use_cache: bool = True
89
+ tie_word_embeddings: bool = False
90
+ rope_parameters: RopeParameters | dict | None = None
91
+ attention_bias: bool = False
92
+ attention_dropout: float | int = 0.0
93
+ head_dim: int = 256
94
+ linear_conv_kernel_dim: int = 4
95
+ linear_key_head_dim: int = 128
96
+ linear_value_head_dim: int = 128
97
+ linear_num_key_heads: int = 16
98
+ linear_num_value_heads: int = 32
99
+ moe_intermediate_size: int = 512
100
+ shared_expert_intermediate_size: int = 512
101
+ num_experts_per_tok: int = 8
102
+ num_experts: int = 256
103
+ output_router_logits: bool = False
104
+ router_aux_loss_coef: float = 0.001
105
+ layer_types: list[str] | None = None
106
+ pad_token_id: int | None = None
107
+ bos_token_id: int | None = None
108
+ eos_token_id: int | list[int] | None = None
109
+ base_config_key = "text_config"
110
+ ignore_keys_at_rope_validation = {"mrope_section", "mrope_interleaved"}
111
+
112
+ def __post_init__(self, **kwargs):
113
+ kwargs.setdefault("partial_rotary_factor", 0.25) # assign default for BC
114
+ if self.layer_types is None:
115
+ interval_pattern = kwargs.pop("full_attention_interval", 4)
116
+ self.layer_types = [
117
+ "linear_attention" if bool((i + 1) % interval_pattern) else "full_attention"
118
+ for i in range(self.num_hidden_layers)
119
+ ]
120
+
121
+ super().__post_init__(**kwargs)
122
+
123
+
124
+ @auto_docstring(checkpoint="Qwen/Qwen3.5-35B-A3B")
125
+ @strict
126
+ class Qwen3_5MoeVisionConfig(PreTrainedConfig):
127
+ r"""
128
+ out_hidden_size (`int`, *optional*, defaults to 3584):
129
+ The output hidden size of the vision model.
130
+ num_position_embeddings (`int`, *optional*, defaults to 2304):
131
+ The maximum sequence length that this model might ever be used with
132
+ """
133
+
134
+ model_type = "qwen3_5_moe_vision"
135
+ base_config_key = "vision_config"
136
+
137
+ depth: int = 27
138
+ hidden_size: int = 1152
139
+ hidden_act: str = "gelu_pytorch_tanh"
140
+ intermediate_size: int = 4304
141
+ num_heads: int = 16
142
+ in_channels: int = 3
143
+ patch_size: int | list[int] | tuple[int, int] = 16
144
+ spatial_merge_size: int = 2
145
+ temporal_patch_size: int | list[int] | tuple[int, int] = 2
146
+ out_hidden_size: int = 3584
147
+ num_position_embeddings: int = 2304
148
+ initializer_range: float = 0.02
149
+
150
+
151
+ @auto_docstring(checkpoint="Qwen/Qwen3.5-35B-A3B")
152
+ @strict
153
+ class Qwen3_5MoeConfig(PreTrainedConfig):
154
+ r"""
155
+ Example:
156
+
157
+ ```python
158
+ >>> from transformers import Qwen3_5MoeForConditionalGeneration, Qwen3_5MoeConfig
159
+
160
+ >>> # Initializing a Qwen3.5-MoE style configuration
161
+ >>> configuration = Qwen3_5MoeConfig()
162
+
163
+ >>> # Initializing a model from the Qwen3.5-35B-A3B style configuration
164
+ >>> model = Qwen3_5MoeForConditionalGeneration(configuration)
165
+
166
+ >>> # Accessing the model configuration
167
+ >>> configuration = model.config
168
+ ```"""
169
+
170
+ model_type = "qwen3_5_moe"
171
+ sub_configs = {"vision_config": Qwen3_5MoeVisionConfig, "text_config": Qwen3_5MoeTextConfig}
172
+ keys_to_ignore_at_inference = ["past_key_values"]
173
+
174
+ text_config: dict | PreTrainedConfig | None = None
175
+ vision_config: dict | PreTrainedConfig | None = None
176
+
177
+ image_token_id: int = 248056
178
+ video_token_id: int = 248057
179
+ vision_start_token_id: int = 248053
180
+ vision_end_token_id: int = 248054
181
+ tie_word_embeddings: bool = False
182
+
183
+ def __post_init__(self, **kwargs):
184
+ if isinstance(self.vision_config, dict):
185
+ self.vision_config = self.sub_configs["vision_config"](**self.vision_config)
186
+ elif self.vision_config is None:
187
+ self.vision_config = self.sub_configs["vision_config"]()
188
+
189
+ if isinstance(self.text_config, dict):
190
+ self.text_config = self.sub_configs["text_config"](**self.text_config)
191
+ elif self.text_config is None:
192
+ self.text_config = self.sub_configs["text_config"]()
193
+
194
+ super().__post_init__(**kwargs)
195
+
196
+
197
+ __all__ = ["Qwen3_5MoeConfig", "Qwen3_5MoeTextConfig", "Qwen3_5MoeVisionConfig"]
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/qwen3_5_moe/modeling_qwen3_5_moe.py ADDED
The diff for this file is too large to render. See raw diff
 
LTA_openwebtext_dualt/mini_owt_logdirichlet/.venv_qwen35_uv/lib/python3.12/site-packages/transformers/models/t5gemma2/configuration_t5gemma2.py ADDED
@@ -0,0 +1,403 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
2
+ # This file was automatically generated from src/transformers/models/t5gemma2/modular_t5gemma2.py.
3
+ # Do NOT edit this file manually as any edits will be overwritten by the generation of
4
+ # the file from the modular. If any change should be done, please apply the change to the
5
+ # modular_t5gemma2.py file directly. One of our CI enforces this.
6
+ # 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨
7
+ # Copyright 2025 Google Inc. HuggingFace Inc. team. All rights reserved.
8
+ #
9
+ #
10
+ # Licensed under the Apache License, Version 2.0 (the "License");
11
+ # you may not use this file except in compliance with the License.
12
+ # You may obtain a copy of the License at
13
+ #
14
+ # http://www.apache.org/licenses/LICENSE-2.0
15
+ #
16
+ # Unless required by applicable law or agreed to in writing, software
17
+ # distributed under the License is distributed on an "AS IS" BASIS,
18
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
+ # See the License for the specific language governing permissions and
20
+ # limitations under the License.
21
+ from typing import Any
22
+
23
+ from huggingface_hub.dataclasses import strict
24
+
25
+ from ...configuration_utils import PreTrainedConfig
26
+ from ...utils import auto_docstring, logging
27
+ from ..siglip import SiglipVisionConfig
28
+
29
+
30
+ logger = logging.get_logger(__name__)
31
+
32
+
33
+ @auto_docstring(checkpoint="google/t5gemma-2-270m-270m")
34
+ @strict
35
+ class T5Gemma2TextConfig(PreTrainedConfig):
36
+ r"""
37
+ query_pre_attn_scalar (`float`, *optional*, defaults to 256):
38
+ Scaling factor used on the attention scores
39
+ final_logit_softcapping (`float`, *optional*):
40
+ Scaling factor when applying tanh softcapping on the logits.
41
+ attn_logit_softcapping (`float`, *optional*):
42
+ Scaling factor when applying tanh softcapping on the attention scores.
43
+ """
44
+
45
+ model_type = "t5gemma2_text"
46
+ keys_to_ignore_at_inference = ["past_key_values"]
47
+ base_model_tp_plan = {
48
+ "layers.*.self_attn.q_proj": "colwise",
49
+ "layers.*.self_attn.k_proj": "colwise",
50
+ "layers.*.self_attn.v_proj": "colwise",
51
+ "layers.*.self_attn.q_norm": "replicated_with_grad_allreduce",
52
+ "layers.*.self_attn.k_norm": "replicated_with_grad_allreduce",
53
+ "layers.*.self_attn.o_proj": "rowwise",
54
+ "layers.*.mlp.gate_proj": "colwise",
55
+ "layers.*.mlp.up_proj": "colwise",
56
+ "layers.*.mlp.down_proj": "rowwise",
57
+ }
58
+ base_model_pp_plan = {
59
+ "embed_tokens": (["input_ids"], ["inputs_embeds"]),
60
+ "layers": (["hidden_states", "attention_mask"], ["hidden_states"]),
61
+ "norm": (["hidden_states"], ["hidden_states"]),
62
+ }
63
+
64
+ vocab_size: int = 262_208
65
+ hidden_size: int = 2304
66
+ intermediate_size: int = 9216
67
+ num_hidden_layers: int = 26
68
+ num_attention_heads: int = 8
69
+ num_key_value_heads: int = 4
70
+ head_dim: int = 256
71
+ hidden_activation: str = "gelu_pytorch_tanh"
72
+ max_position_embeddings: int = 131_072
73
+ initializer_range: float = 0.02
74
+ rms_norm_eps: float = 1e-6
75
+ use_cache: bool = True
76
+ pad_token_id: int | None = 0
77
+ eos_token_id: int | list[int] | None = 1
78
+ bos_token_id: int | None = 2
79
+ tie_word_embeddings: bool = True
80
+ rope_parameters: dict | None = None
81
+ attention_bias: bool = False
82
+ attention_dropout: int | float | None = 0.0
83
+ query_pre_attn_scalar: int = 256
84
+ sliding_window: int | None = 4096
85
+ layer_types: list[str] | None = None
86
+ final_logit_softcapping: float | None = None
87
+ attn_logit_softcapping: float | None = None
88
+ default_theta = {"global": 1_000_000.0, "local": 10_000.0}
89
+
90
+ def __post_init__(self, **kwargs):
91
+ # BC -> the pattern used to be a simple int, and it's still present in configs on the Hub
92
+ _sliding_window_pattern = kwargs.pop("sliding_window_pattern", 6)
93
+ if self.layer_types is None:
94
+ self.layer_types = [
95
+ "sliding_attention" if bool((i + 1) % _sliding_window_pattern) else "full_attention"
96
+ for i in range(self.num_hidden_layers)
97
+ ]
98
+
99
+ super().__post_init__(**kwargs)
100
+
101
+ def validate_architecture(self):
102
+ """Part of `@strict`-powered validation. Validates the architecture of the config."""
103
+ if self.hidden_size % self.num_attention_heads != 0:
104
+ raise ValueError(
105
+ f"The hidden size ({self.hidden_size}) is not a multiple of the number of attention "
106
+ f"heads ({self.num_attention_heads})."
107
+ )
108
+
109
+ def convert_rope_params_to_dict(self, **kwargs):
110
+ rope_scaling = kwargs.pop("rope_scaling", None)
111
+
112
+ # Try to set `rope_scaling` if available, otherwise use `rope_parameters`. If we find `rope_parameters`
113
+ # as arg in the inputs, we can safely assume that it is in the new format. New naming used -> new format
114
+ default_rope_params = {
115
+ "sliding_attention": {"rope_type": "default"},
116
+ "full_attention": {"rope_type": "default"},
117
+ }
118
+ self.rope_parameters = self.rope_parameters if self.rope_parameters is not None else default_rope_params
119
+ if rope_scaling is not None:
120
+ self.rope_parameters["full_attention"].update(rope_scaling)
121
+
122
+ # Set default values if not present
123
+ if self.rope_parameters.get("full_attention") is None:
124
+ self.rope_parameters["full_attention"] = {"rope_type": "default"}
125
+ self.rope_parameters["full_attention"].setdefault(
126
+ "rope_theta", kwargs.pop("rope_theta", self.default_theta["global"])
127
+ )
128
+ if self.rope_parameters.get("sliding_attention") is None:
129
+ self.rope_parameters["sliding_attention"] = {"rope_type": "default"}
130
+ self.rope_parameters["sliding_attention"].setdefault(
131
+ "rope_theta", kwargs.pop("rope_local_base_freq", self.default_theta["local"])
132
+ )
133
+
134
+ # Standardize and validate the correctness of rotary position embeddings parameters
135
+ self.standardize_rope_params()
136
+ return kwargs
137
+
138
+
139
+ @auto_docstring(checkpoint="google/t5gemma-2-270m-270m")
140
+ @strict
141
+ class T5Gemma2EncoderConfig(PreTrainedConfig):
142
+ r"""
143
+ mm_tokens_per_image (`int`, *optional*, defaults to 256):
144
+ The number of tokens per image embedding.
145
+ boi_token_index (`int`, *optional*, defaults to 255999):
146
+ The begin-of-image token index to wrap the image prompt.
147
+ eoi_token_index (`int`, *optional*, defaults to 256000):
148
+ The end-of-image token index to wrap the image prompt.
149
+
150
+ Example:
151
+
152
+ ```python
153
+ >>> from transformers import T5Gemma2EncoderForConditionalGeneration, T5Gemma2EncoderConfig, SiglipVisionConfig, T5Gemma2EncoderTextConfig
154
+
155
+ >>> # Initializing a Siglip-like vision config
156
+ >>> vision_config = SiglipVisionConfig()
157
+
158
+ >>> # Initializing a T5Gemma2Encoder Text config
159
+ >>> text_config = T5Gemma2EncoderTextConfig()
160
+
161
+ >>> # Initializing a T5Gemma2Encoder gemma-3-4b style configuration
162
+ >>> configuration = T5Gemma2EncoderConfig(vision_config, text_config)
163
+
164
+ >>> # Initializing a model from the gemma-3-4b style configuration
165
+ >>> model = T5Gemma2EncoderTextConfig(configuration)
166
+
167
+ >>> # Accessing the model configuration
168
+ >>> configuration = model.config
169
+ ```"""
170
+
171
+ model_type = "t5gemma2_encoder"
172
+ attribute_map = {
173
+ "image_token_id": "image_token_index",
174
+ "boi_token_id": "boi_token_index",
175
+ "eoi_token_id": "eoi_token_index",
176
+ }
177
+
178
+ sub_configs = {
179
+ "text_config": T5Gemma2TextConfig,
180
+ "vision_config": SiglipVisionConfig,
181
+ }
182
+
183
+ text_config: T5Gemma2TextConfig | dict[str, Any] | None = None
184
+ vision_config: SiglipVisionConfig | dict[str, Any] | None = None
185
+ mm_tokens_per_image: int | None = 256
186
+ boi_token_index: int | None = 255_999
187
+ eoi_token_index: int | None = 256_000
188
+ image_token_index: int | None = 262_144
189
+ initializer_range: float | None = 0.02
190
+ tie_word_embeddings: bool | None = True
191
+
192
+ def __post_init__(self, **kwargs):
193
+ if self.text_config is None:
194
+ self.text_config = T5Gemma2TextConfig()
195
+ logger.info("text_config is None, using default T5Gemma2EncoderTextConfig text config.")
196
+ elif isinstance(self.text_config, dict):
197
+ self.text_config = T5Gemma2TextConfig(**self.text_config)
198
+
199
+ if isinstance(self.vision_config, dict):
200
+ self.vision_config = SiglipVisionConfig(**self.vision_config)
201
+ elif self.vision_config is None:
202
+ self.vision_config = SiglipVisionConfig()
203
+ logger.info("vision_config is None, using default SiglipVisionConfig vision config.")
204
+
205
+ super().__post_init__(**kwargs)
206
+
207
+
208
+ @auto_docstring(checkpoint="google/t5gemma-2-270m-270m")
209
+ @strict
210
+ class T5Gemma2DecoderConfig(PreTrainedConfig):
211
+ r"""
212
+ query_pre_attn_scalar (`float`, *optional*, defaults to 256):
213
+ Scaling factor used on the attention scores
214
+ final_logit_softcapping (`float`, *optional*):
215
+ Scaling factor when applying tanh softcapping on the logits.
216
+ attn_logit_softcapping (`float`, *optional*):
217
+ Scaling factor when applying tanh softcapping on the attention scores.
218
+ """
219
+
220
+ model_type = "t5gemma2_decoder"
221
+ keys_to_ignore_at_inference = ["past_key_values"]
222
+ base_model_tp_plan = {
223
+ "layers.*.self_attn.q_proj": "colwise",
224
+ "layers.*.self_attn.k_proj": "colwise",
225
+ "layers.*.self_attn.v_proj": "colwise",
226
+ "layers.*.self_attn.q_norm": "replicated_with_grad_allreduce",
227
+ "layers.*.self_attn.k_norm": "replicated_with_grad_allreduce",
228
+ "layers.*.self_attn.o_proj": "rowwise",
229
+ "layers.*.mlp.gate_proj": "colwise",
230
+ "layers.*.mlp.up_proj": "colwise",
231
+ "layers.*.mlp.down_proj": "rowwise",
232
+ }
233
+ base_model_pp_plan = {
234
+ "embed_tokens": (["input_ids"], ["inputs_embeds"]),
235
+ "layers": (["hidden_states", "attention_mask"], ["hidden_states"]),
236
+ "norm": (["hidden_states"], ["hidden_states"]),
237
+ }
238
+
239
+ vocab_size: int = 262_208
240
+ hidden_size: int = 2304
241
+ intermediate_size: int = 9216
242
+ num_hidden_layers: int = 26
243
+ num_attention_heads: int = 8
244
+ num_key_value_heads: int = 4
245
+ head_dim: int = 256
246
+ hidden_activation: str = "gelu_pytorch_tanh"
247
+ max_position_embeddings: int = 131_072
248
+ initializer_range: float = 0.02
249
+ rms_norm_eps: float = 1e-6
250
+ use_cache: bool = True
251
+ pad_token_id: int | None = 0
252
+ eos_token_id: int | list[int] | None = 1
253
+ bos_token_id: int | None = 2
254
+ tie_word_embeddings: bool = True
255
+ rope_parameters: dict | None = None
256
+ attention_bias: bool = False
257
+ attention_dropout: int | float | None = 0.0
258
+ query_pre_attn_scalar: int = 256
259
+ sliding_window: int | None = 4096
260
+ layer_types: list[str] | None = None
261
+ final_logit_softcapping: float | None = None
262
+ attn_logit_softcapping: float | None = None
263
+ default_theta = {"global": 1_000_000.0, "local": 10_000.0}
264
+
265
+ def __post_init__(self, **kwargs):
266
+ # BC -> the pattern used to be a simple int, and it's still present in configs on the Hub
267
+ _sliding_window_pattern = kwargs.pop("sliding_window_pattern", 6)
268
+ if self.layer_types is None:
269
+ self.layer_types = [
270
+ "sliding_attention" if bool((i + 1) % _sliding_window_pattern) else "full_attention"
271
+ for i in range(self.num_hidden_layers)
272
+ ]
273
+
274
+ super().__post_init__(**kwargs)
275
+
276
+ def validate_architecture(self):
277
+ """Part of `@strict`-powered validation. Validates the architecture of the config."""
278
+ if self.hidden_size % self.num_attention_heads != 0:
279
+ raise ValueError(
280
+ f"The hidden size ({self.hidden_size}) is not a multiple of the number of attention "
281
+ f"heads ({self.num_attention_heads})."
282
+ )
283
+
284
+ def convert_rope_params_to_dict(self, **kwargs):
285
+ rope_scaling = kwargs.pop("rope_scaling", None)
286
+
287
+ # Try to set `rope_scaling` if available, otherwise use `rope_parameters`. If we find `rope_parameters`
288
+ # as arg in the inputs, we can safely assume that it is in the new format. New naming used -> new format
289
+ default_rope_params = {
290
+ "sliding_attention": {"rope_type": "default"},
291
+ "full_attention": {"rope_type": "default"},
292
+ }
293
+ self.rope_parameters = self.rope_parameters if self.rope_parameters is not None else default_rope_params
294
+ if rope_scaling is not None:
295
+ self.rope_parameters["full_attention"].update(rope_scaling)
296
+
297
+ # Set default values if not present
298
+ if self.rope_parameters.get("full_attention") is None:
299
+ self.rope_parameters["full_attention"] = {"rope_type": "default"}
300
+ self.rope_parameters["full_attention"].setdefault(
301
+ "rope_theta", kwargs.pop("rope_theta", self.default_theta["global"])
302
+ )
303
+ if self.rope_parameters.get("sliding_attention") is None:
304
+ self.rope_parameters["sliding_attention"] = {"rope_type": "default"}
305
+ self.rope_parameters["sliding_attention"].setdefault(
306
+ "rope_theta", kwargs.pop("rope_local_base_freq", self.default_theta["local"])
307
+ )
308
+
309
+ # Standardize and validate the correctness of rotary position embeddings parameters
310
+ self.standardize_rope_params()
311
+ return kwargs
312
+
313
+
314
+ @auto_docstring(checkpoint="google/t5gemma-2-270m-270m")
315
+ @strict
316
+ class T5Gemma2Config(PreTrainedConfig):
317
+ r"""
318
+ encoder (`Union[T5Gemma2EncoderConfig, dict]`, optional, *optional*):
319
+ Configuration for the encoder.
320
+ decoder (`Union[T5Gemma2DecoderConfig, dict]`, optional, *optional*):
321
+ Configuration for the decoder.
322
+ eoi_token_index (`int`, *optional*):
323
+ The end-of-image token index to wrap the image prompt. Will be same as
324
+ `self.encoder.eoi_token_index`
325
+
326
+ ```python
327
+ >>> from transformers import T5Gemma2Config, T5Gemma2Model
328
+ >>> t5gemma2_config = T5Gemma2Config.from_pretrained("google/t5gemma-270m-270m")
329
+ >>> model = T5Gemma2Model(t5gemma2_config)
330
+ ```
331
+ """
332
+
333
+ model_type = "t5gemma2"
334
+ keys_to_ignore_at_inference = ["past_key_values"]
335
+
336
+ sub_configs = {
337
+ "encoder": T5Gemma2EncoderConfig,
338
+ "decoder": T5Gemma2DecoderConfig,
339
+ }
340
+
341
+ attribute_map = {
342
+ "image_token_id": "image_token_index",
343
+ "eoi_token_id": "eoi_token_index",
344
+ }
345
+
346
+ encoder: T5Gemma2EncoderConfig | dict[str, Any] | None = None
347
+ decoder: T5Gemma2DecoderConfig | dict[str, Any] | None = None
348
+ is_encoder_decoder: bool = True
349
+ dropout_rate: float | int = 0.0
350
+ attention_dropout: float | int = 0.0
351
+ classifier_dropout_rate: float | int = 0.0
352
+ initializer_range: float = 0.02
353
+ image_token_index: int = 256_001
354
+ eoi_token_index: int | None = None
355
+ tie_word_embeddings: bool = True
356
+
357
+ def __post_init__(self, **kwargs):
358
+ if isinstance(self.encoder, dict):
359
+ self.encoder = T5Gemma2EncoderConfig(**self.encoder)
360
+ elif self.encoder is None:
361
+ self.encoder = T5Gemma2EncoderConfig()
362
+ logger.info("encoder is None, using default T5Gemma2EncoderConfig encoder config.")
363
+
364
+ if isinstance(self.decoder, dict):
365
+ self.decoder = T5Gemma2DecoderConfig(**self.decoder)
366
+ elif self.decoder is None:
367
+ self.decoder = T5Gemma2DecoderConfig()
368
+ logger.info("decoder is None, using default T5Gemma2DecoderConfig decoder config.")
369
+
370
+ self.encoder.text_config.dropout_rate = self.dropout_rate
371
+ self.encoder.text_config.attention_dropout = self.attention_dropout
372
+ self.encoder.vision_config.attention_dropout = self.attention_dropout
373
+ self.encoder.image_token_index = self.image_token_index
374
+
375
+ self.decoder.dropout_rate = self.dropout_rate
376
+ self.decoder.attention_dropout = self.attention_dropout
377
+ self.eoi_token_index = self.encoder.eoi_token_index
378
+
379
+ for special_token_key in ["bos_token_id", "pad_token_id", "eos_token_id", "vocab_size"]:
380
+ if special_token_key not in kwargs:
381
+ kwargs[special_token_key] = getattr(self.decoder, special_token_key)
382
+
383
+ super().__post_init__(**kwargs)
384
+
385
+ def validate_architecture(self):
386
+ """Part of `@strict`-powered validation. Validates the architecture of the config."""
387
+ if self.encoder.text_config.hidden_size != self.decoder.hidden_size:
388
+ raise ValueError(
389
+ "Imbalanced encoder-decoder is not supported in T5Gemma2: "
390
+ f"encoder ({self.encoder.text_config.hidden_size}) vs decoder ({self.decoder.hidden_size})."
391
+ )
392
+
393
+ if not self.is_encoder_decoder:
394
+ raise ValueError("T5Gemma2Model only support encoder-decoder modeling.")
395
+
396
+ if self.encoder.text_config.vocab_size != self.decoder.vocab_size:
397
+ raise ValueError(
398
+ "Imbalanced encoder-decoder vocabulary size is not supported in T5Gemma2: "
399
+ f"encoder ({self.encoder.text_config.vocab_size}) vs decoder ({self.decoder.vocab_size})."
400
+ )
401
+
402
+
403
+ __all__ = ["T5Gemma2Config", "T5Gemma2TextConfig", "T5Gemma2EncoderConfig", "T5Gemma2DecoderConfig"]