Release frozen VimeML tiny-ja-v1 FP32 and Core ML INT8 (GPL-2.0)
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- LICENSE +339 -0
- README.md +112 -1
- RELEASE.json +481 -0
- SHA256SUMS.txt +118 -0
- coreml/ios18-int8-block32/manifest.json +491 -0
- coreml/ios18-int8-block32/model.mlpackage/Data/com.apple.CoreML/model.mlmodel +3 -0
- coreml/ios18-int8-block32/model.mlpackage/Data/com.apple.CoreML/weights/weight.bin +3 -0
- coreml/ios18-int8-block32/model.mlpackage/Manifest.json +18 -0
- evaluation/summary.json +239 -0
- infer.py +36 -0
- inference/config.json +9 -0
- inference/manifest.json +108 -0
- inference/token-manifest.json +119 -0
- inference/tokenizer.model +3 -0
- inference/weights.pt +3 -0
- source/LICENSE +339 -0
- source/README.md +3 -0
- source/configs/corpus-parallel.toml +35 -0
- source/configs/corpus-sharded.toml +35 -0
- source/configs/ime-eval-v1.json +54 -0
- source/configs/ime-homophones.json +18 -0
- source/configs/inference-prompts.json +14 -0
- source/configs/loader.toml +8 -0
- source/configs/phrase-demo-prompts.json +22 -0
- source/configs/tokenizer.toml +25 -0
- source/configs/train-smoke.toml +37 -0
- source/configs/train-v1.toml +40 -0
- source/requirements.txt +20 -0
- source/scripts/benchmarks/evaluate.py +11 -0
- source/scripts/benchmarks/evaluate_ajimee.py +11 -0
- source/scripts/benchmarks/export_cached_development.py +28 -0
- source/scripts/benchmarks/generate.py +11 -0
- source/scripts/benchmarks/generate_development.py +10 -0
- source/scripts/benchmarks/hybrid.py +10 -0
- source/scripts/benchmarks/prepare_ajimee.py +11 -0
- source/scripts/corpus/build.py +12 -0
- source/scripts/corpus/merge.py +33 -0
- source/scripts/corpus/preprocess.py +12 -0
- source/scripts/deployment/ane_output_probe.py +72 -0
- source/scripts/deployment/compare_quantization.py +119 -0
- source/scripts/deployment/compute_plan.py +57 -0
- source/scripts/deployment/coreml.py +11 -0
- source/scripts/deployment/coreml_ane.py +91 -0
- source/scripts/deployment/coreml_conservative.py +229 -0
- source/scripts/deployment/package_handoff.py +117 -0
- source/scripts/deployment/package_ios.py +76 -0
- source/scripts/deployment/summarize_keyboard_trace.py +77 -0
- source/scripts/deployment/summarize_memory.py +59 -0
- source/scripts/publishing/hub.py +50 -0
- source/scripts/publishing/prepare_hf.py +212 -0
LICENSE
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
GNU GENERAL PUBLIC LICENSE
|
| 2 |
+
Version 2, June 1991
|
| 3 |
+
|
| 4 |
+
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
| 5 |
+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
| 6 |
+
Everyone is permitted to copy and distribute verbatim copies
|
| 7 |
+
of this license document, but changing it is not allowed.
|
| 8 |
+
|
| 9 |
+
Preamble
|
| 10 |
+
|
| 11 |
+
The licenses for most software are designed to take away your
|
| 12 |
+
freedom to share and change it. By contrast, the GNU General Public
|
| 13 |
+
License is intended to guarantee your freedom to share and change free
|
| 14 |
+
software--to make sure the software is free for all its users. This
|
| 15 |
+
General Public License applies to most of the Free Software
|
| 16 |
+
Foundation's software and to any other program whose authors commit to
|
| 17 |
+
using it. (Some other Free Software Foundation software is covered by
|
| 18 |
+
the GNU Lesser General Public License instead.) You can apply it to
|
| 19 |
+
your programs, too.
|
| 20 |
+
|
| 21 |
+
When we speak of free software, we are referring to freedom, not
|
| 22 |
+
price. Our General Public Licenses are designed to make sure that you
|
| 23 |
+
have the freedom to distribute copies of free software (and charge for
|
| 24 |
+
this service if you wish), that you receive source code or can get it
|
| 25 |
+
if you want it, that you can change the software or use pieces of it
|
| 26 |
+
in new free programs; and that you know you can do these things.
|
| 27 |
+
|
| 28 |
+
To protect your rights, we need to make restrictions that forbid
|
| 29 |
+
anyone to deny you these rights or to ask you to surrender the rights.
|
| 30 |
+
These restrictions translate to certain responsibilities for you if you
|
| 31 |
+
distribute copies of the software, or if you modify it.
|
| 32 |
+
|
| 33 |
+
For example, if you distribute copies of such a program, whether
|
| 34 |
+
gratis or for a fee, you must give the recipients all the rights that
|
| 35 |
+
you have. You must make sure that they, too, receive or can get the
|
| 36 |
+
source code. And you must show them these terms so they know their
|
| 37 |
+
rights.
|
| 38 |
+
|
| 39 |
+
We protect your rights with two steps: (1) copyright the software, and
|
| 40 |
+
(2) offer you this license which gives you legal permission to copy,
|
| 41 |
+
distribute and/or modify the software.
|
| 42 |
+
|
| 43 |
+
Also, for each author's protection and ours, we want to make certain
|
| 44 |
+
that everyone understands that there is no warranty for this free
|
| 45 |
+
software. If the software is modified by someone else and passed on, we
|
| 46 |
+
want its recipients to know that what they have is not the original, so
|
| 47 |
+
that any problems introduced by others will not reflect on the original
|
| 48 |
+
authors' reputations.
|
| 49 |
+
|
| 50 |
+
Finally, any free program is threatened constantly by software
|
| 51 |
+
patents. We wish to avoid the danger that redistributors of a free
|
| 52 |
+
program will individually obtain patent licenses, in effect making the
|
| 53 |
+
program proprietary. To prevent this, we have made it clear that any
|
| 54 |
+
patent must be licensed for everyone's free use or not licensed at all.
|
| 55 |
+
|
| 56 |
+
The precise terms and conditions for copying, distribution and
|
| 57 |
+
modification follow.
|
| 58 |
+
|
| 59 |
+
GNU GENERAL PUBLIC LICENSE
|
| 60 |
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
| 61 |
+
|
| 62 |
+
0. This License applies to any program or other work which contains
|
| 63 |
+
a notice placed by the copyright holder saying it may be distributed
|
| 64 |
+
under the terms of this General Public License. The "Program", below,
|
| 65 |
+
refers to any such program or work, and a "work based on the Program"
|
| 66 |
+
means either the Program or any derivative work under copyright law:
|
| 67 |
+
that is to say, a work containing the Program or a portion of it,
|
| 68 |
+
either verbatim or with modifications and/or translated into another
|
| 69 |
+
language. (Hereinafter, translation is included without limitation in
|
| 70 |
+
the term "modification".) Each licensee is addressed as "you".
|
| 71 |
+
|
| 72 |
+
Activities other than copying, distribution and modification are not
|
| 73 |
+
covered by this License; they are outside its scope. The act of
|
| 74 |
+
running the Program is not restricted, and the output from the Program
|
| 75 |
+
is covered only if its contents constitute a work based on the
|
| 76 |
+
Program (independent of having been made by running the Program).
|
| 77 |
+
Whether that is true depends on what the Program does.
|
| 78 |
+
|
| 79 |
+
1. You may copy and distribute verbatim copies of the Program's
|
| 80 |
+
source code as you receive it, in any medium, provided that you
|
| 81 |
+
conspicuously and appropriately publish on each copy an appropriate
|
| 82 |
+
copyright notice and disclaimer of warranty; keep intact all the
|
| 83 |
+
notices that refer to this License and to the absence of any warranty;
|
| 84 |
+
and give any other recipients of the Program a copy of this License
|
| 85 |
+
along with the Program.
|
| 86 |
+
|
| 87 |
+
You may charge a fee for the physical act of transferring a copy, and
|
| 88 |
+
you may at your option offer warranty protection in exchange for a fee.
|
| 89 |
+
|
| 90 |
+
2. You may modify your copy or copies of the Program or any portion
|
| 91 |
+
of it, thus forming a work based on the Program, and copy and
|
| 92 |
+
distribute such modifications or work under the terms of Section 1
|
| 93 |
+
above, provided that you also meet all of these conditions:
|
| 94 |
+
|
| 95 |
+
a) You must cause the modified files to carry prominent notices
|
| 96 |
+
stating that you changed the files and the date of any change.
|
| 97 |
+
|
| 98 |
+
b) You must cause any work that you distribute or publish, that in
|
| 99 |
+
whole or in part contains or is derived from the Program or any
|
| 100 |
+
part thereof, to be licensed as a whole at no charge to all third
|
| 101 |
+
parties under the terms of this License.
|
| 102 |
+
|
| 103 |
+
c) If the modified program normally reads commands interactively
|
| 104 |
+
when run, you must cause it, when started running for such
|
| 105 |
+
interactive use in the most ordinary way, to print or display an
|
| 106 |
+
announcement including an appropriate copyright notice and a
|
| 107 |
+
notice that there is no warranty (or else, saying that you provide
|
| 108 |
+
a warranty) and that users may redistribute the program under
|
| 109 |
+
these conditions, and telling the user how to view a copy of this
|
| 110 |
+
License. (Exception: if the Program itself is interactive but
|
| 111 |
+
does not normally print such an announcement, your work based on
|
| 112 |
+
the Program is not required to print an announcement.)
|
| 113 |
+
|
| 114 |
+
These requirements apply to the modified work as a whole. If
|
| 115 |
+
identifiable sections of that work are not derived from the Program,
|
| 116 |
+
and can be reasonably considered independent and separate works in
|
| 117 |
+
themselves, then this License, and its terms, do not apply to those
|
| 118 |
+
sections when you distribute them as separate works. But when you
|
| 119 |
+
distribute the same sections as part of a whole which is a work based
|
| 120 |
+
on the Program, the distribution of the whole must be on the terms of
|
| 121 |
+
this License, whose permissions for other licensees extend to the
|
| 122 |
+
entire whole, and thus to each and every part regardless of who wrote it.
|
| 123 |
+
|
| 124 |
+
Thus, it is not the intent of this section to claim rights or contest
|
| 125 |
+
your rights to work written entirely by you; rather, the intent is to
|
| 126 |
+
exercise the right to control the distribution of derivative or
|
| 127 |
+
collective works based on the Program.
|
| 128 |
+
|
| 129 |
+
In addition, mere aggregation of another work not based on the Program
|
| 130 |
+
with the Program (or with a work based on the Program) on a volume of
|
| 131 |
+
a storage or distribution medium does not bring the other work under
|
| 132 |
+
the scope of this License.
|
| 133 |
+
|
| 134 |
+
3. You may copy and distribute the Program (or a work based on it,
|
| 135 |
+
under Section 2) in object code or executable form under the terms of
|
| 136 |
+
Sections 1 and 2 above provided that you also do one of the following:
|
| 137 |
+
|
| 138 |
+
a) Accompany it with the complete corresponding machine-readable
|
| 139 |
+
source code, which must be distributed under the terms of Sections
|
| 140 |
+
1 and 2 above on a medium customarily used for software interchange; or,
|
| 141 |
+
|
| 142 |
+
b) Accompany it with a written offer, valid for at least three
|
| 143 |
+
years, to give any third party, for a charge no more than your
|
| 144 |
+
cost of physically performing source distribution, a complete
|
| 145 |
+
machine-readable copy of the corresponding source code, to be
|
| 146 |
+
distributed under the terms of Sections 1 and 2 above on a medium
|
| 147 |
+
customarily used for software interchange; or,
|
| 148 |
+
|
| 149 |
+
c) Accompany it with the information you received as to the offer
|
| 150 |
+
to distribute corresponding source code. (This alternative is
|
| 151 |
+
allowed only for noncommercial distribution and only if you
|
| 152 |
+
received the program in object code or executable form with such
|
| 153 |
+
an offer, in accord with Subsection b above.)
|
| 154 |
+
|
| 155 |
+
The source code for a work means the preferred form of the work for
|
| 156 |
+
making modifications to it. For an executable work, complete source
|
| 157 |
+
code means all the source code for all modules it contains, plus any
|
| 158 |
+
associated interface definition files, plus the scripts used to
|
| 159 |
+
control compilation and installation of the executable. However, as a
|
| 160 |
+
special exception, the source code distributed need not include
|
| 161 |
+
anything that is normally distributed (in either source or binary
|
| 162 |
+
form) with the major components (compiler, kernel, and so on) of the
|
| 163 |
+
operating system on which the executable runs, unless that component
|
| 164 |
+
itself accompanies the executable.
|
| 165 |
+
|
| 166 |
+
If distribution of executable or object code is made by offering
|
| 167 |
+
access to copy from a designated place, then offering equivalent
|
| 168 |
+
access to copy the source code from the same place counts as
|
| 169 |
+
distribution of the source code, even though third parties are not
|
| 170 |
+
compelled to copy the source along with the object code.
|
| 171 |
+
|
| 172 |
+
4. You may not copy, modify, sublicense, or distribute the Program
|
| 173 |
+
except as expressly provided under this License. Any attempt
|
| 174 |
+
otherwise to copy, modify, sublicense or distribute the Program is
|
| 175 |
+
void, and will automatically terminate your rights under this License.
|
| 176 |
+
However, parties who have received copies, or rights, from you under
|
| 177 |
+
this License will not have their licenses terminated so long as such
|
| 178 |
+
parties remain in full compliance.
|
| 179 |
+
|
| 180 |
+
5. You are not required to accept this License, since you have not
|
| 181 |
+
signed it. However, nothing else grants you permission to modify or
|
| 182 |
+
distribute the Program or its derivative works. These actions are
|
| 183 |
+
prohibited by law if you do not accept this License. Therefore, by
|
| 184 |
+
modifying or distributing the Program (or any work based on the
|
| 185 |
+
Program), you indicate your acceptance of this License to do so, and
|
| 186 |
+
all its terms and conditions for copying, distributing or modifying
|
| 187 |
+
the Program or works based on it.
|
| 188 |
+
|
| 189 |
+
6. Each time you redistribute the Program (or any work based on the
|
| 190 |
+
Program), the recipient automatically receives a license from the
|
| 191 |
+
original licensor to copy, distribute or modify the Program subject to
|
| 192 |
+
these terms and conditions. You may not impose any further
|
| 193 |
+
restrictions on the recipients' exercise of the rights granted herein.
|
| 194 |
+
You are not responsible for enforcing compliance by third parties to
|
| 195 |
+
this License.
|
| 196 |
+
|
| 197 |
+
7. If, as a consequence of a court judgment or allegation of patent
|
| 198 |
+
infringement or for any other reason (not limited to patent issues),
|
| 199 |
+
conditions are imposed on you (whether by court order, agreement or
|
| 200 |
+
otherwise) that contradict the conditions of this License, they do not
|
| 201 |
+
excuse you from the conditions of this License. If you cannot
|
| 202 |
+
distribute so as to satisfy simultaneously your obligations under this
|
| 203 |
+
License and any other pertinent obligations, then as a consequence you
|
| 204 |
+
may not distribute the Program at all. For example, if a patent
|
| 205 |
+
license would not permit royalty-free redistribution of the Program by
|
| 206 |
+
all those who receive copies directly or indirectly through you, then
|
| 207 |
+
the only way you could satisfy both it and this License would be to
|
| 208 |
+
refrain entirely from distribution of the Program.
|
| 209 |
+
|
| 210 |
+
If any portion of this section is held invalid or unenforceable under
|
| 211 |
+
any particular circumstance, the balance of the section is intended to
|
| 212 |
+
apply and the section as a whole is intended to apply in other
|
| 213 |
+
circumstances.
|
| 214 |
+
|
| 215 |
+
It is not the purpose of this section to induce you to infringe any
|
| 216 |
+
patents or other property right claims or to contest validity of any
|
| 217 |
+
such claims; this section has the sole purpose of protecting the
|
| 218 |
+
integrity of the free software distribution system, which is
|
| 219 |
+
implemented by public license practices. Many people have made
|
| 220 |
+
generous contributions to the wide range of software distributed
|
| 221 |
+
through that system in reliance on consistent application of that
|
| 222 |
+
system; it is up to the author/donor to decide if he or she is willing
|
| 223 |
+
to distribute software through any other system and a licensee cannot
|
| 224 |
+
impose that choice.
|
| 225 |
+
|
| 226 |
+
This section is intended to make thoroughly clear what is believed to
|
| 227 |
+
be a consequence of the rest of this License.
|
| 228 |
+
|
| 229 |
+
8. If the distribution and/or use of the Program is restricted in
|
| 230 |
+
certain countries either by patents or by copyrighted interfaces, the
|
| 231 |
+
original copyright holder who places the Program under this License
|
| 232 |
+
may add an explicit geographical distribution limitation excluding
|
| 233 |
+
those countries, so that distribution is permitted only in or among
|
| 234 |
+
countries not thus excluded. In such case, this License incorporates
|
| 235 |
+
the limitation as if written in the body of this License.
|
| 236 |
+
|
| 237 |
+
9. The Free Software Foundation may publish revised and/or new versions
|
| 238 |
+
of the General Public License from time to time. Such new versions will
|
| 239 |
+
be similar in spirit to the present version, but may differ in detail to
|
| 240 |
+
address new problems or concerns.
|
| 241 |
+
|
| 242 |
+
Each version is given a distinguishing version number. If the Program
|
| 243 |
+
specifies a version number of this License which applies to it and "any
|
| 244 |
+
later version", you have the option of following the terms and conditions
|
| 245 |
+
either of that version or of any later version published by the Free
|
| 246 |
+
Software Foundation. If the Program does not specify a version number of
|
| 247 |
+
this License, you may choose any version ever published by the Free Software
|
| 248 |
+
Foundation.
|
| 249 |
+
|
| 250 |
+
10. If you wish to incorporate parts of the Program into other free
|
| 251 |
+
programs whose distribution conditions are different, write to the author
|
| 252 |
+
to ask for permission. For software which is copyrighted by the Free
|
| 253 |
+
Software Foundation, write to the Free Software Foundation; we sometimes
|
| 254 |
+
make exceptions for this. Our decision will be guided by the two goals
|
| 255 |
+
of preserving the free status of all derivatives of our free software and
|
| 256 |
+
of promoting the sharing and reuse of software generally.
|
| 257 |
+
|
| 258 |
+
NO WARRANTY
|
| 259 |
+
|
| 260 |
+
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
| 261 |
+
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
| 262 |
+
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
| 263 |
+
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
| 264 |
+
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
| 265 |
+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
| 266 |
+
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
| 267 |
+
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
| 268 |
+
REPAIR OR CORRECTION.
|
| 269 |
+
|
| 270 |
+
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
| 271 |
+
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
| 272 |
+
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
| 273 |
+
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
| 274 |
+
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
| 275 |
+
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
| 276 |
+
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
| 277 |
+
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
| 278 |
+
POSSIBILITY OF SUCH DAMAGES.
|
| 279 |
+
|
| 280 |
+
END OF TERMS AND CONDITIONS
|
| 281 |
+
|
| 282 |
+
How to Apply These Terms to Your New Programs
|
| 283 |
+
|
| 284 |
+
If you develop a new program, and you want it to be of the greatest
|
| 285 |
+
possible use to the public, the best way to achieve this is to make it
|
| 286 |
+
free software which everyone can redistribute and change under these terms.
|
| 287 |
+
|
| 288 |
+
To do so, attach the following notices to the program. It is safest
|
| 289 |
+
to attach them to the start of each source file to most effectively
|
| 290 |
+
convey the exclusion of warranty; and each file should have at least
|
| 291 |
+
the "copyright" line and a pointer to where the full notice is found.
|
| 292 |
+
|
| 293 |
+
<one line to give the program's name and a brief idea of what it does.>
|
| 294 |
+
Copyright (C) <year> <name of author>
|
| 295 |
+
|
| 296 |
+
This program is free software; you can redistribute it and/or modify
|
| 297 |
+
it under the terms of the GNU General Public License as published by
|
| 298 |
+
the Free Software Foundation; either version 2 of the License, or
|
| 299 |
+
(at your option) any later version.
|
| 300 |
+
|
| 301 |
+
This program is distributed in the hope that it will be useful,
|
| 302 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 303 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 304 |
+
GNU General Public License for more details.
|
| 305 |
+
|
| 306 |
+
You should have received a copy of the GNU General Public License along
|
| 307 |
+
with this program; if not, write to the Free Software Foundation, Inc.,
|
| 308 |
+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
| 309 |
+
|
| 310 |
+
Also add information on how to contact you by electronic and paper mail.
|
| 311 |
+
|
| 312 |
+
If the program is interactive, make it output a short notice like this
|
| 313 |
+
when it starts in an interactive mode:
|
| 314 |
+
|
| 315 |
+
Gnomovision version 69, Copyright (C) year name of author
|
| 316 |
+
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
| 317 |
+
This is free software, and you are welcome to redistribute it
|
| 318 |
+
under certain conditions; type `show c' for details.
|
| 319 |
+
|
| 320 |
+
The hypothetical commands `show w' and `show c' should show the appropriate
|
| 321 |
+
parts of the General Public License. Of course, the commands you use may
|
| 322 |
+
be called something other than `show w' and `show c'; they could even be
|
| 323 |
+
mouse-clicks or menu items--whatever suits your program.
|
| 324 |
+
|
| 325 |
+
You should also get your employer (if you work as a programmer) or your
|
| 326 |
+
school, if any, to sign a "copyright disclaimer" for the program, if
|
| 327 |
+
necessary. Here is a sample; alter the names:
|
| 328 |
+
|
| 329 |
+
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
| 330 |
+
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
| 331 |
+
|
| 332 |
+
<signature of Ty Coon>, 1 April 1989
|
| 333 |
+
Ty Coon, President of Vice
|
| 334 |
+
|
| 335 |
+
This General Public License does not permit incorporating your program into
|
| 336 |
+
proprietary programs. If your program is a subroutine library, you may
|
| 337 |
+
consider it more useful to permit linking proprietary applications with the
|
| 338 |
+
library. If this is what you want to do, use the GNU Lesser General
|
| 339 |
+
Public License instead of this License.
|
README.md
CHANGED
|
@@ -1,3 +1,114 @@
|
|
| 1 |
---
|
| 2 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
language:
|
| 3 |
+
- ja
|
| 4 |
+
license: gpl-2.0
|
| 5 |
+
pipeline_tag: text-generation
|
| 6 |
+
tags:
|
| 7 |
+
- pytorch
|
| 8 |
+
- coreml
|
| 9 |
+
- japanese
|
| 10 |
+
- causal-lm
|
| 11 |
+
- contextual-reranking
|
| 12 |
+
- tiny-gpt
|
| 13 |
---
|
| 14 |
+
|
| 15 |
+
# VimeML Tiny Japanese GPT v1
|
| 16 |
+
|
| 17 |
+
A frozen **7,386,624-parameter**, decoder-only Japanese language model for local contextual candidate reranking and short within-sentence continuation. This repository provides the FP32 inference bundle and an iOS18 INT8-weight Core ML variant. SentencePiece tokenization, kana candidate retrieval, scoring and search run outside the Core ML graph.
|
| 18 |
+
|
| 19 |
+
This is a custom PyTorch model, not a Transformers `AutoModel` integration or an instruction/chat model. The source model, loader, scoring and conversion code are included under `source/`; no `trust_remote_code` or training checkpoint is needed.
|
| 20 |
+
|
| 21 |
+
## Files and identity
|
| 22 |
+
|
| 23 |
+
| Path | Contents |
|
| 24 |
+
| --- | --- |
|
| 25 |
+
| `inference/` | Unique FP32 state_dict, config, original SentencePiece model, token manifest and provenance manifest; no optimizer |
|
| 26 |
+
| `coreml/ios18-int8-block32/` | Original Core ML `.mlpackage` and manifest |
|
| 27 |
+
| `source/` | Frozen VimeML Python source, conversion scripts, configuration and unified requirements |
|
| 28 |
+
| `infer.py` | Read-only wrapper around the original fingerprint-checked loader, generation and scoring |
|
| 29 |
+
| `evaluation/summary.json` | Curated results and source report hashes, without benchmark texts or device traces |
|
| 30 |
+
| `RELEASE.json`, `SHA256SUMS.txt`, `verify_release.py` | Release inventory and local byte verification |
|
| 31 |
+
|
| 32 |
+
- Source repository: [Voltline/VimeML](https://github.com/Voltline/VimeML), commit **9f0409ef7970c468efb622b207b1089de09651c1**.
|
| 33 |
+
- Inference manifest SHA256: `4284cdc5491513cc817633081677b363b14f59c0b4ffb78cdf7fcfb221f71b3c`.
|
| 34 |
+
- Core ML manifest SHA256: `a9d516233fa57aaadd09477e2e909760972ff49b5577919f8a441c489f5c2245`.
|
| 35 |
+
- Tokenizer SHA256: `d9f1ba1e456ce72dd9c06a62b12e804cf14090c30179e6078cd51d03063b2982`.
|
| 36 |
+
- Original training checkpoint SHA256: `93b6139aa05031df02038efcaf26788bc9916712919f3d2a4c4f398615cef75b`; the training checkpoint is not distributed here.
|
| 37 |
+
|
| 38 |
+
The original manifests remain byte-for-byte intact. Their old absolute paths describe provenance, not paths required on a downloader's machine. Core ML conversion scripts evolved after the original experiment; the old manifest's script hash is retained.
|
| 39 |
+
|
| 40 |
+
## Architecture and tokenization
|
| 41 |
+
|
| 42 |
+
Pre-LayerNorm GPT with GELU, learned absolute positions and causal attention: vocabulary 16,384; context length 128; width 256; 4 layers; 4 heads; FFN width 1024. Input embedding and LM head share one parameter. There is no KV cache or sliding context. Each generation step recomputes the entire prefix.
|
| 43 |
+
|
| 44 |
+
SentencePiece 0.2.1 unigram, identity normalization, whitespace preservation and byte fallback. PAD/UNK/BOS/EOS IDs are 0/1/2/3. The exact original `tokenizer.model` is required; retraining a tokenizer does not preserve this vocabulary binding.
|
| 45 |
+
|
| 46 |
+
## Quick start: downloaded files
|
| 47 |
+
|
| 48 |
+
Python ≥3.11. After downloading the repository, install the included unified requirements. Select the appropriate PyTorch build first if needed; do not use the PyTorch-only package index for the whole requirements file. The Darwin branch pins the original Core ML tool environment; no Core ML prediction occurs during FP32 inference.
|
| 49 |
+
|
| 50 |
+
```sh
|
| 51 |
+
python -m pip install -r source/requirements.txt
|
| 52 |
+
python verify_release.py
|
| 53 |
+
python infer.py --prompt "今日は雨が降っているので、" --max-new-tokens 8
|
| 54 |
+
python infer.py --prompt "雨が降っているので、" --candidate "傘を持っていく" --candidate "橋を渡っていく"
|
| 55 |
+
```
|
| 56 |
+
|
| 57 |
+
The second inference command ranks the supplied strings using the original contextual suffix logP sum. It does not perform kana conversion or dictionary lookup. Invalid/overlong candidates raise in this diagnostic wrapper; the application implementation retains the dictionary order on eligibility failure.
|
| 58 |
+
|
| 59 |
+
The FP32 loader checks all bundle files and the included source fingerprints, restores the shared head, and uses `torch.load(..., weights_only=True)`. Keep the source, tokenizer and inference files together. `verify_release.py` checks every release file without loading a model; checksums detect altered bytes but are not a digital signature.
|
| 60 |
+
|
| 61 |
+
## Candidate scoring
|
| 62 |
+
|
| 63 |
+
Encode `context + candidate` jointly. Cancel the common token prefix across BOS+context and the jointly encoded candidate sequences, then sum original full-vocabulary log-softmax values over the remaining suffix. Do not add a candidate-final EOS. Ties preserve the original order. This token suffix likelihood is a scoring proxy, not exact string conditional probability.
|
| 64 |
+
|
| 65 |
+
Deployment uses **pure LM scoring**; AzooKey retrieves kana candidates. The older FP32 `AzooKey score + 2 × LM sum` policy is a historical comparison, not the INT8 deployment policy. Quantization does not establish that λ=2 remains optimal.
|
| 66 |
+
|
| 67 |
+
## Training and evaluation
|
| 68 |
+
|
| 69 |
+
Training used nine local shards of [FineWeb2-Edu Japanese](https://huggingface.co/datasets/hotchpotch/fineweb-2-edu-japanese) and Japanese [Tatoeba](https://tatoeba.org/), cleaned, split into sentences, exactly deduplicated and grouped across 98%/1%/1% train/validation/test splits. There were 25,713,003 unique sentences and 25,185,368 training sentences. The tokenizer learned from 2 million sampled training sentences.
|
| 70 |
+
|
| 71 |
+
One data pass, 196,853 updates and 573,295,237 prediction targets. The frozen best checkpoint's complete validation loss is 4.5415708951, perplexity 93.8380942. Fixed-subset validation selected the checkpoint; the test split was not used for training, checkpoint selection or tuning. No test perplexity is claimed.
|
| 72 |
+
|
| 73 |
+
Reranking uses fixed N-best 20 AzooKey candidates, without injecting correct answers. [AJIMEE JWTD_v2/v1](https://github.com/azooKey/AJIMEE-Bench) has 200 cases and allows multiple accepted spellings. The synthetic development set has 137 reviewed cases.
|
| 74 |
+
|
| 75 |
+
| Frozen pool | AzooKey original Top-1 | FP32 pure LM Top-1 / Top-5 | INT8 pure LM Top-1 / Top-5 | Pool coverage |
|
| 76 |
+
| --- | ---: | ---: | ---: | ---: |
|
| 77 |
+
| Development | 111/137 | 122/137 / 134/137 | 122/137 / 134/137 | 136/137 |
|
| 78 |
+
| AJIMEE | 87/200 | 124/200 / 151/200 | 124/200 / 151/200 | 162/200 |
|
| 79 |
+
|
| 80 |
+
INT8 vs Windows FP32: development changes 119 complete rankings and 0 first choices; AJIMEE changes 163 complete rankings and 2 first choices, both between acceptable spellings. The original development compression report instead compares against uncompressed conservative Core ML: 118 complete rankings change. Equal hit counts do not mean equal scores or complete rankings. See the release summary for the separate baselines and hashes.
|
| 81 |
+
|
| 82 |
+
## Core ML variant
|
| 83 |
+
|
| 84 |
+
**Weight-only symmetric INT8, block size 32; FP32 computation; CPU_ONLY; minimum iOS 18.** It is not INT8 activation or arithmetic inference. Logical `.mlpackage` size is **8,077,801 bytes**. This is not compiled size, IPA size or resident memory.
|
| 85 |
+
|
| 86 |
+
Input `input_ids`: INT32 `[1,T]`, 1≤T≤128. Output `logits`: FLOAT32 `[1,T,16384]`, full raw vocabulary logits. Only right-side PAD is supported. Shared embedding/head are retained. Use `.cpuOnly`; GPU/ALL paths for this package triggered a quantized-gather assertion in the client experiments.
|
| 87 |
+
|
| 88 |
+
On Mac, compile manually for the target platform before integrating:
|
| 89 |
+
|
| 90 |
+
```sh
|
| 91 |
+
xcrun coremlcompiler compile coreml/ios18-int8-block32/model.mlpackage compiled-int8 --deployment-target 18.0
|
| 92 |
+
```
|
| 93 |
+
|
| 94 |
+
The INT8 model **fails the strict FP32 logits alignment gate** (maximum absolute difference about 3.66). Candidate fixtures, causal and right-PAD checks passed, and the frozen pool hit counts above were preserved. Do not describe the model as numerically identical to FP32.
|
| 95 |
+
|
| 96 |
+
An AJIMEE-text diagnostic reported mean KL(FP32‖INT8)≈0.00589, mean NLL 5.56698→5.57289 and position top-choice agreement 94.4%. These are means of per-example position means, not a corpus token-weighted aggregate. Text content was capped at 127 tokens plus BOS; the old report did not record truncation counts. Similar aggregate KL to a simulated INT8 recipe does not prove exact conversion equivalence. Tested palette4 group16 degraded substantially and is not included.
|
| 97 |
+
|
| 98 |
+
## Performance evidence and limits
|
| 99 |
+
|
| 100 |
+
Recorded iPhone 16 Pro Max optimized CPU_ONLY **test-host App** results: approximately 14 candidate reranking p50 10.4ms/p95 12.7ms; next-word p50 5.8ms; T128 prediction 3.0ms. Host memory increased by about 24.2MB and peaked at 74.8MB. These are not keyboard-extension latency or memory measurements.
|
| 101 |
+
|
| 102 |
+
A separate 152.7 second manual real-keyboard recording produced 127 approximately 1 second samples: physical footprint peak 21.25MiB and private resident peak 51.922MiB. The user confirmed LM ranking and next-word suggestions; installed build/model hashes were not independently captured. Short spikes may have been missed, the tail still grew slowly, and long-session stability is not certified. The different memory metrics cannot be substituted for one another. No energy claim is made.
|
| 103 |
+
|
| 104 |
+
## Intended use and limitations
|
| 105 |
+
|
| 106 |
+
Japanese within-sentence reranking and short completion experiments, primarily for on-device input methods. The model is small, not instruction-tuned, and can repeat text, drift, truncate or invent facts. Outputs need product-level review; the fixed beam suite had only 10/20 prefixes with clearly natural suggestions in an AI review. These offline pool metrics do not measure application-wide accuracy or guarantee keyboard performance.
|
| 107 |
+
|
| 108 |
+
Semantic near-duplicates and training overlap with public evaluation text have not been comprehensively audited. AJIMEE has been used for error analysis and is not a fresh blind test. Development labels and review came from AI, not native-speaker adjudication. Official benchmark context can cross sentences, while the client uses current-sentence context. Candidate coverage limits reranking accuracy.
|
| 109 |
+
|
| 110 |
+
## License and attribution
|
| 111 |
+
|
| 112 |
+
Model weights and the included VimeML code are released under **GNU GPL v2.0**, chosen by the author. See `LICENSE` and `source/LICENSE`. Training data and third-party software retain their own terms; they are not relicensed by this model repository.
|
| 113 |
+
|
| 114 |
+
FineWeb2-Edu Japanese's dataset card declares ODC-BY; [Tatoeba text terms](https://tatoeba.org/en/terms_of_use) default to CC-BY 2.0 FR with author attribution requirements. No corpus text is redistributed here. AJIMEE's source data is CC-BY-SA 3.0; this release distributes aggregate metrics, not its evaluation text. SentencePiece runtime code is not vendored into this release; installed dependencies retain their upstream licenses. Source configuration and training/conversion implementations are included, while datasets, API responses, optimizer state, device traces and the separate Vime client are excluded.
|
RELEASE.json
ADDED
|
@@ -0,0 +1,481 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"format": "vimeml_hf_release_v1",
|
| 3 |
+
"repo_id": "Voltline/vimeml-tiny-ja-v1",
|
| 4 |
+
"license": "gpl-2.0",
|
| 5 |
+
"source_repository": "https://github.com/Voltline/VimeML",
|
| 6 |
+
"source_commit": "9f0409ef7970c468efb622b207b1089de09651c1",
|
| 7 |
+
"created_utc": "2026-10-06T14:54:06.938207+00:00",
|
| 8 |
+
"bundle_manifest_sha256": "4284cdc5491513cc817633081677b363b14f59c0b4ffb78cdf7fcfb221f71b3c",
|
| 9 |
+
"coreml_manifest_sha256": "a9d516233fa57aaadd09477e2e909760972ff49b5577919f8a441c489f5c2245",
|
| 10 |
+
"files": {
|
| 11 |
+
"coreml/ios18-int8-block32/manifest.json": {
|
| 12 |
+
"bytes": 13273,
|
| 13 |
+
"sha256": "a9d516233fa57aaadd09477e2e909760972ff49b5577919f8a441c489f5c2245"
|
| 14 |
+
},
|
| 15 |
+
"coreml/ios18-int8-block32/model.mlpackage/Data/com.apple.CoreML/model.mlmodel": {
|
| 16 |
+
"bytes": 46400,
|
| 17 |
+
"sha256": "22e80193abc7672bbcf2a3fc214a186ae6e64d76c1e1b42ead38fef5a003cd37"
|
| 18 |
+
},
|
| 19 |
+
"coreml/ios18-int8-block32/model.mlpackage/Data/com.apple.CoreML/weights/weight.bin": {
|
| 20 |
+
"bytes": 8030784,
|
| 21 |
+
"sha256": "d3a063455371e624cf208fb6ed76fc9ac6addd8c2f87eaebf4653649f85b8109"
|
| 22 |
+
},
|
| 23 |
+
"coreml/ios18-int8-block32/model.mlpackage/Manifest.json": {
|
| 24 |
+
"bytes": 617,
|
| 25 |
+
"sha256": "31b13734848024036806cbd5bacf405eddba6c4451e5659b25f714ffe1766ee5"
|
| 26 |
+
},
|
| 27 |
+
"evaluation/summary.json": {
|
| 28 |
+
"bytes": 9055,
|
| 29 |
+
"sha256": "d0fe405a4f68c3e5f94541834ab9f60cf0937b4f2fd6c50d25737e6ab828ad0e"
|
| 30 |
+
},
|
| 31 |
+
"infer.py": {
|
| 32 |
+
"bytes": 1528,
|
| 33 |
+
"sha256": "8ed8d241d349a4e88840dd841da9db3191ec9f0db84c8f8165a951fa84720621"
|
| 34 |
+
},
|
| 35 |
+
"inference/config.json": {
|
| 36 |
+
"bytes": 145,
|
| 37 |
+
"sha256": "8950524f2f3a0373f3a0ebbcde79a8feaa54949ed926830c287b384306adf9ca"
|
| 38 |
+
},
|
| 39 |
+
"inference/manifest.json": {
|
| 40 |
+
"bytes": 4746,
|
| 41 |
+
"sha256": "4284cdc5491513cc817633081677b363b14f59c0b4ffb78cdf7fcfb221f71b3c"
|
| 42 |
+
},
|
| 43 |
+
"inference/token-manifest.json": {
|
| 44 |
+
"bytes": 6208,
|
| 45 |
+
"sha256": "c7ebf3672d46cfc75d12013c34f35fb7ac9eac613f29f3454be0cb0e991854dc"
|
| 46 |
+
},
|
| 47 |
+
"inference/tokenizer.model": {
|
| 48 |
+
"bytes": 284118,
|
| 49 |
+
"sha256": "d9f1ba1e456ce72dd9c06a62b12e804cf14090c30179e6078cd51d03063b2982"
|
| 50 |
+
},
|
| 51 |
+
"inference/weights.pt": {
|
| 52 |
+
"bytes": 29562119,
|
| 53 |
+
"sha256": "1cdac16913068bfdcfa94b139ecb34d945d0e9483a863373a6dca4397e3cd355"
|
| 54 |
+
},
|
| 55 |
+
"LICENSE": {
|
| 56 |
+
"bytes": 18431,
|
| 57 |
+
"sha256": "189b1af95d661151e054cea10c91b3d754e4de4d3fecfb074c1fb29476f7167b"
|
| 58 |
+
},
|
| 59 |
+
"README.md": {
|
| 60 |
+
"bytes": 10728,
|
| 61 |
+
"sha256": "366194211cc7db2f7de4f82471796b543f829e4c646a984758f2a5d589556f70"
|
| 62 |
+
},
|
| 63 |
+
"source/configs/corpus-parallel.toml": {
|
| 64 |
+
"bytes": 1239,
|
| 65 |
+
"sha256": "67e3bf5c3166c9c5fa847ec515c44dd41dfebee56134265df2c5b13bec14ad9a"
|
| 66 |
+
},
|
| 67 |
+
"source/configs/corpus-sharded.toml": {
|
| 68 |
+
"bytes": 1179,
|
| 69 |
+
"sha256": "49f06564931dc4be63f76cdde8cd3be78ddeb81a45cbada768e0a0ca8191a49d"
|
| 70 |
+
},
|
| 71 |
+
"source/configs/ime-eval-v1.json": {
|
| 72 |
+
"bytes": 8368,
|
| 73 |
+
"sha256": "46d0b4eba6293a2fa2e7ef16d9132c6320e9d2da80921d60aa939e90e35dc222"
|
| 74 |
+
},
|
| 75 |
+
"source/configs/ime-homophones.json": {
|
| 76 |
+
"bytes": 1195,
|
| 77 |
+
"sha256": "61c475fba63964b540e55be39d70e786886c059ce58fee94465517f648f021fe"
|
| 78 |
+
},
|
| 79 |
+
"source/configs/inference-prompts.json": {
|
| 80 |
+
"bytes": 685,
|
| 81 |
+
"sha256": "e701173b553617086ad2ab679313423eabb19e89d9f51fd31b321336584652ea"
|
| 82 |
+
},
|
| 83 |
+
"source/configs/loader.toml": {
|
| 84 |
+
"bytes": 249,
|
| 85 |
+
"sha256": "e8baa76da3e223bcb3b333f96994ef4e86eeecb62cea18503eb8f7ad9c4a74cf"
|
| 86 |
+
},
|
| 87 |
+
"source/configs/phrase-demo-prompts.json": {
|
| 88 |
+
"bytes": 1500,
|
| 89 |
+
"sha256": "b51e101d6a4bc34c4a375439191e4adbd63d511ccc62b49c4d5b758decee17ed"
|
| 90 |
+
},
|
| 91 |
+
"source/configs/tokenizer.toml": {
|
| 92 |
+
"bytes": 658,
|
| 93 |
+
"sha256": "28396838808e5745c4d2251e90e095d2a2e816033526bcb154d1c74c98dfe9b5"
|
| 94 |
+
},
|
| 95 |
+
"source/configs/train-smoke.toml": {
|
| 96 |
+
"bytes": 791,
|
| 97 |
+
"sha256": "2d386dd8efe0ffd0da6df319226daf7bab8948b1bcb2abc7afb59c45d98d28b3"
|
| 98 |
+
},
|
| 99 |
+
"source/configs/train-v1.toml": {
|
| 100 |
+
"bytes": 900,
|
| 101 |
+
"sha256": "44ba93246d406d5187c496ad2cf23d1533e6f581a8d6dc6f7fff03fca22b8323"
|
| 102 |
+
},
|
| 103 |
+
"source/LICENSE": {
|
| 104 |
+
"bytes": 18431,
|
| 105 |
+
"sha256": "189b1af95d661151e054cea10c91b3d754e4de4d3fecfb074c1fb29476f7167b"
|
| 106 |
+
},
|
| 107 |
+
"source/README.md": {
|
| 108 |
+
"bytes": 274,
|
| 109 |
+
"sha256": "5184082e7c857b4ab965d3c5b7366a0d5b56d98cdb5e40511dda6d0c2e298290"
|
| 110 |
+
},
|
| 111 |
+
"source/requirements.txt": {
|
| 112 |
+
"bytes": 968,
|
| 113 |
+
"sha256": "0fac5689cead9021745847b2753294a9a4d95c002a61762f7f25254db2a26489"
|
| 114 |
+
},
|
| 115 |
+
"source/scripts/benchmarks/evaluate.py": {
|
| 116 |
+
"bytes": 278,
|
| 117 |
+
"sha256": "34a2a24d14c0e8b20c44dafab720075cbc23261a7fdbe71091dff12200e7fc24"
|
| 118 |
+
},
|
| 119 |
+
"source/scripts/benchmarks/evaluate_ajimee.py": {
|
| 120 |
+
"bytes": 291,
|
| 121 |
+
"sha256": "a28fc24da1f8cbb6972b49dc0223361e16c7b093872d92df6bd52aabd00bd54a"
|
| 122 |
+
},
|
| 123 |
+
"source/scripts/benchmarks/export_cached_development.py": {
|
| 124 |
+
"bytes": 1024,
|
| 125 |
+
"sha256": "d328ff258e4a8fa83e51be099f5fa8fbf480f2d377579c475c355f9f01263bf6"
|
| 126 |
+
},
|
| 127 |
+
"source/scripts/benchmarks/generate.py": {
|
| 128 |
+
"bytes": 269,
|
| 129 |
+
"sha256": "de9866c56cd846073a3a3a82b1553ab737ccb911001d17de71839865057d0293"
|
| 130 |
+
},
|
| 131 |
+
"source/scripts/benchmarks/generate_development.py": {
|
| 132 |
+
"bytes": 279,
|
| 133 |
+
"sha256": "3b3b4192535a035bbf57e3f51f1fb16a0647b1a3fc060a179b7ae9fb1127cc41"
|
| 134 |
+
},
|
| 135 |
+
"source/scripts/benchmarks/hybrid.py": {
|
| 136 |
+
"bytes": 281,
|
| 137 |
+
"sha256": "64dbd0fcee7e294bd290bbf9f2057e81656ede4e0b328cdae710360da24716b3"
|
| 138 |
+
},
|
| 139 |
+
"source/scripts/benchmarks/prepare_ajimee.py": {
|
| 140 |
+
"bytes": 272,
|
| 141 |
+
"sha256": "3935e16a81c389c5a3dd74da6da38732ff32b668ea3c6d0484c52f017657706a"
|
| 142 |
+
},
|
| 143 |
+
"source/scripts/corpus/build.py": {
|
| 144 |
+
"bytes": 271,
|
| 145 |
+
"sha256": "0e4d753adf6cf97cc19b975e4f35d3cea41a4f519782f6b8eeea3309260486df"
|
| 146 |
+
},
|
| 147 |
+
"source/scripts/corpus/merge.py": {
|
| 148 |
+
"bytes": 1335,
|
| 149 |
+
"sha256": "dd6639d55b9aecdbf46d20fec98ab78422ff53ad14ec5a4a39d6a43e824cd0d6"
|
| 150 |
+
},
|
| 151 |
+
"source/scripts/corpus/preprocess.py": {
|
| 152 |
+
"bytes": 279,
|
| 153 |
+
"sha256": "f8181f1b055661a1097d2bf80654ac59af4cf6a8b74afecb8f44b40e3d94d4f8"
|
| 154 |
+
},
|
| 155 |
+
"source/scripts/deployment/ane_output_probe.py": {
|
| 156 |
+
"bytes": 3786,
|
| 157 |
+
"sha256": "e3e12fd3373119539eb3ed23eaccbc1457cafa7a22ae444dd4b187c118d883ce"
|
| 158 |
+
},
|
| 159 |
+
"source/scripts/deployment/compare_quantization.py": {
|
| 160 |
+
"bytes": 6534,
|
| 161 |
+
"sha256": "9a0761dbd3ece9b730ed0e52010ef965a8415b4320188c31e1863ab0c874d2fd"
|
| 162 |
+
},
|
| 163 |
+
"source/scripts/deployment/compute_plan.py": {
|
| 164 |
+
"bytes": 2759,
|
| 165 |
+
"sha256": "2aa26fb2f2b59a630cc9cafb7eb684f237c44c780c1ec820badbbd07d8f2bf41"
|
| 166 |
+
},
|
| 167 |
+
"source/scripts/deployment/coreml.py": {
|
| 168 |
+
"bytes": 278,
|
| 169 |
+
"sha256": "7f321ab43b41acd4765045a93edc5c3ec874dcb741541a3f7460d13f8c27f50e"
|
| 170 |
+
},
|
| 171 |
+
"source/scripts/deployment/coreml_ane.py": {
|
| 172 |
+
"bytes": 4674,
|
| 173 |
+
"sha256": "28c67b5b30c3ad93a46703dad62236b2cd81ec5478ebf2cd9974e7b336001871"
|
| 174 |
+
},
|
| 175 |
+
"source/scripts/deployment/coreml_conservative.py": {
|
| 176 |
+
"bytes": 14097,
|
| 177 |
+
"sha256": "61b290658385ee40325263be24b1a1dffdc18fe5bc494dd02a1bf93bf301b986"
|
| 178 |
+
},
|
| 179 |
+
"source/scripts/deployment/package_handoff.py": {
|
| 180 |
+
"bytes": 6406,
|
| 181 |
+
"sha256": "65db41ee70efb5409738ece23eb41750e695f1746e42b85314198d72710fa7a7"
|
| 182 |
+
},
|
| 183 |
+
"source/scripts/deployment/package_ios.py": {
|
| 184 |
+
"bytes": 4266,
|
| 185 |
+
"sha256": "1228adeb409e3cf095aa7890390307b9cd518c535fc23365f5a8ffc01b144448"
|
| 186 |
+
},
|
| 187 |
+
"source/scripts/deployment/summarize_keyboard_trace.py": {
|
| 188 |
+
"bytes": 4106,
|
| 189 |
+
"sha256": "0857bab4b1dcf81ec8b1ae5e680672cf512d5547aa3246c1e2a7ad7bfc0b79e5"
|
| 190 |
+
},
|
| 191 |
+
"source/scripts/deployment/summarize_memory.py": {
|
| 192 |
+
"bytes": 3339,
|
| 193 |
+
"sha256": "a798a4478ba907f0b4c88246c90d865063fa5c7c02f10456e7faceea7a7966ba"
|
| 194 |
+
},
|
| 195 |
+
"source/scripts/publishing/hub.py": {
|
| 196 |
+
"bytes": 2825,
|
| 197 |
+
"sha256": "bbd7f36ed4682bcdcb5e4c5d87b42733106dbaebf6f949fcd60cd498dc059274"
|
| 198 |
+
},
|
| 199 |
+
"source/scripts/publishing/prepare_hf.py": {
|
| 200 |
+
"bytes": 12512,
|
| 201 |
+
"sha256": "994c690a95f8d13d15a1ab1671185c8e2744537f48d667c176f9a3079b3630e9"
|
| 202 |
+
},
|
| 203 |
+
"source/scripts/review/approve.py": {
|
| 204 |
+
"bytes": 273,
|
| 205 |
+
"sha256": "555b275e74482c597a26b3cbc23ffb1648e636801bc5ddeccf7c25df176414d0"
|
| 206 |
+
},
|
| 207 |
+
"source/scripts/review/prepare.py": {
|
| 208 |
+
"bytes": 273,
|
| 209 |
+
"sha256": "77578100f9aaae50cabac68a85996dcf02479179f6d17fbf30368ea7aa70ab5f"
|
| 210 |
+
},
|
| 211 |
+
"source/scripts/review/run.py": {
|
| 212 |
+
"bytes": 269,
|
| 213 |
+
"sha256": "d18a127f4a08b84ac03a398f3c96c935a0b6275fe0e7b1af2f3e3d4d92ec49b1"
|
| 214 |
+
},
|
| 215 |
+
"source/scripts/review/run_multi_key.py": {
|
| 216 |
+
"bytes": 282,
|
| 217 |
+
"sha256": "702ba0084944c8db433f1d12f64e6933659965a9a125434cce80f916f63c6f47"
|
| 218 |
+
},
|
| 219 |
+
"source/scripts/tokenizer/encode.py": {
|
| 220 |
+
"bytes": 284,
|
| 221 |
+
"sha256": "46af106351c8835ba0e001295c4d2122c8c629d799c913feb8292d2e83100670"
|
| 222 |
+
},
|
| 223 |
+
"source/scripts/tokenizer/train.py": {
|
| 224 |
+
"bytes": 274,
|
| 225 |
+
"sha256": "1001c67f565711d91c59335b342ab1a3e3fdb40f7f5642a8a49ce9ac46a4823d"
|
| 226 |
+
},
|
| 227 |
+
"source/scripts/tools/check_corpus.py": {
|
| 228 |
+
"bytes": 282,
|
| 229 |
+
"sha256": "231f867355c0cd2806e0ee20378c9671443309f2716db9dbf1426fda6bbe9eb6"
|
| 230 |
+
},
|
| 231 |
+
"source/scripts/tools/inspect_data.py": {
|
| 232 |
+
"bytes": 350,
|
| 233 |
+
"sha256": "fd5a05f0c74e4d3bd95097a37be009422ec348c3fd3e36f1ca12740c02309760"
|
| 234 |
+
},
|
| 235 |
+
"source/scripts/tools/phrase_demo.py": {
|
| 236 |
+
"bytes": 274,
|
| 237 |
+
"sha256": "09d81377f63d9c967e444ffdaaec83a7228de8109c4492a5175b46a8590387bc"
|
| 238 |
+
},
|
| 239 |
+
"source/scripts/training/check_data.py": {
|
| 240 |
+
"bytes": 278,
|
| 241 |
+
"sha256": "fce755bfd04595f95d6a021c5d2533599d3463542239da198d65e4c26a716e0a"
|
| 242 |
+
},
|
| 243 |
+
"source/scripts/training/evaluate_ime.py": {
|
| 244 |
+
"bytes": 274,
|
| 245 |
+
"sha256": "81729525388462eb93ede97f917f0f6eae1ef6518c35d169e19dc745f37ffa4d"
|
| 246 |
+
},
|
| 247 |
+
"source/scripts/training/infer.py": {
|
| 248 |
+
"bytes": 252,
|
| 249 |
+
"sha256": "6f409f7761d543e65d5f4c8886c8f59e0929b4b299977a8439bd0d13623755f4"
|
| 250 |
+
},
|
| 251 |
+
"source/scripts/training/train.py": {
|
| 252 |
+
"bytes": 263,
|
| 253 |
+
"sha256": "56b5781f98b3440d23d1516d830e83356db3a0b04c9aab134368c2ef9cefb91c"
|
| 254 |
+
},
|
| 255 |
+
"source/scripts/training/train_wandb.py": {
|
| 256 |
+
"bytes": 3345,
|
| 257 |
+
"sha256": "db40a3f34315dcd409f0b22d8633c569f71f6807841fb2551a9ca423869ca149"
|
| 258 |
+
},
|
| 259 |
+
"source/src/vimeml/__init__.py": {
|
| 260 |
+
"bytes": 52,
|
| 261 |
+
"sha256": "ff0f42adee5b707f35ea0ba1307e65d8a2f632a55c3281c8f446211032f0fbc1"
|
| 262 |
+
},
|
| 263 |
+
"source/src/vimeml/benchmarks/__init__.py": {
|
| 264 |
+
"bytes": 77,
|
| 265 |
+
"sha256": "03a0b8a9e43ef3ecf56189a86fe7e33d9633d4a766edf02583e911aef9bde581"
|
| 266 |
+
},
|
| 267 |
+
"source/src/vimeml/benchmarks/ajimee.py": {
|
| 268 |
+
"bytes": 6566,
|
| 269 |
+
"sha256": "4916651168f3f883161ebbbc24db5e1ae5b1bc4cd6abf8c7b83560ef960406cb"
|
| 270 |
+
},
|
| 271 |
+
"source/src/vimeml/benchmarks/development.py": {
|
| 272 |
+
"bytes": 36457,
|
| 273 |
+
"sha256": "d74e8f9e888c115c6a9ce27f5b08ea40efb332c087d94e372d4c33364b2dc2d4"
|
| 274 |
+
},
|
| 275 |
+
"source/src/vimeml/benchmarks/evaluate.py": {
|
| 276 |
+
"bytes": 9097,
|
| 277 |
+
"sha256": "867cd2f41b49043dd985e7f05e788f3f83a0ac47a4d0d9b2d6306dcd0c96b02a"
|
| 278 |
+
},
|
| 279 |
+
"source/src/vimeml/benchmarks/evaluate_ajimee.py": {
|
| 280 |
+
"bytes": 13783,
|
| 281 |
+
"sha256": "459a8c0d1bb4f8ffba57e92ee2c8bb3f5278c3e4a1a5bcc5dfda48a21bde3716"
|
| 282 |
+
},
|
| 283 |
+
"source/src/vimeml/benchmarks/generate.py": {
|
| 284 |
+
"bytes": 28505,
|
| 285 |
+
"sha256": "9a468c23ea3ebf02f1184b1742cbe11a025f2a0d7ae57e0ee2e54468de72a1d7"
|
| 286 |
+
},
|
| 287 |
+
"source/src/vimeml/benchmarks/hybrid.py": {
|
| 288 |
+
"bytes": 20442,
|
| 289 |
+
"sha256": "71267f445ac92736f1dabf03c3e77193e9f2a1323f23fa1bc060aff4fbe4ea7e"
|
| 290 |
+
},
|
| 291 |
+
"source/src/vimeml/corpus/__init__.py": {
|
| 292 |
+
"bytes": 32,
|
| 293 |
+
"sha256": "55cdd3f899dd7ad156f8987cf2ba2bbbc76a95dfaba33a319058b4d01e2f9947"
|
| 294 |
+
},
|
| 295 |
+
"source/src/vimeml/corpus/build.py": {
|
| 296 |
+
"bytes": 12675,
|
| 297 |
+
"sha256": "895b6894c4b85e72c8655cf6b42e21d51b51736d649ec2adb6841e033f4ac1f9"
|
| 298 |
+
},
|
| 299 |
+
"source/src/vimeml/data/__init__.py": {
|
| 300 |
+
"bytes": 30,
|
| 301 |
+
"sha256": "86d655d2d715fcb2f73269c1ffbfc9e87d9080a1baaf389f88e30de6022fdc19"
|
| 302 |
+
},
|
| 303 |
+
"source/src/vimeml/data/annotations.py": {
|
| 304 |
+
"bytes": 6610,
|
| 305 |
+
"sha256": "ba62919c8084d24cb3f41c451e970b5448e7b0f5407340c28cca0b220d387395"
|
| 306 |
+
},
|
| 307 |
+
"source/src/vimeml/data/build.py": {
|
| 308 |
+
"bytes": 29679,
|
| 309 |
+
"sha256": "d7d63e1ea9a2f9da9fe92ff2773b792c7ca89911b2d7058a2709fcbbc443081e"
|
| 310 |
+
},
|
| 311 |
+
"source/src/vimeml/data/clean.py": {
|
| 312 |
+
"bytes": 1791,
|
| 313 |
+
"sha256": "ee88adbb74d5a03f591231484928becf0a62557c85702efddd214c9bc8a2354f"
|
| 314 |
+
},
|
| 315 |
+
"source/src/vimeml/data/corpus_export.py": {
|
| 316 |
+
"bytes": 8056,
|
| 317 |
+
"sha256": "d2e943aae1e2942076b1db8430067e048fcdc71d46761bb329f7fa460e843280"
|
| 318 |
+
},
|
| 319 |
+
"source/src/vimeml/data/corpus_parts.py": {
|
| 320 |
+
"bytes": 10178,
|
| 321 |
+
"sha256": "c196a78e5096e659eb8c536602e009c98de346bd82084c29f9384e526055f6f6"
|
| 322 |
+
},
|
| 323 |
+
"source/src/vimeml/data/merge_parts.py": {
|
| 324 |
+
"bytes": 8755,
|
| 325 |
+
"sha256": "43cb87845d17e52261675073b010269c53e4c79a8e5e16237d2627c9e07116e6"
|
| 326 |
+
},
|
| 327 |
+
"source/src/vimeml/data/merge_parts_fast.py": {
|
| 328 |
+
"bytes": 27413,
|
| 329 |
+
"sha256": "600dc56899dfa6ac2eda639cf79f6ad5e789642b99d6c68569262f593bfc3642"
|
| 330 |
+
},
|
| 331 |
+
"source/src/vimeml/data/preprocess_part.py": {
|
| 332 |
+
"bytes": 6553,
|
| 333 |
+
"sha256": "433a93f18809aa1b11a13c8e63edce2a73864140fbaf4a4bcff0c7ab475be164"
|
| 334 |
+
},
|
| 335 |
+
"source/src/vimeml/data/readers.py": {
|
| 336 |
+
"bytes": 4734,
|
| 337 |
+
"sha256": "837017b0282f62ed68c9a47c69da3ed12fe39b74e7f88bc3ae16113f55b679b6"
|
| 338 |
+
},
|
| 339 |
+
"source/src/vimeml/data/segment.py": {
|
| 340 |
+
"bytes": 8309,
|
| 341 |
+
"sha256": "9834f4867e126f229e86a7fc5b7481f4c803c05d00a21966a78ec293095b0f8c"
|
| 342 |
+
},
|
| 343 |
+
"source/src/vimeml/deployment/__init__.py": {
|
| 344 |
+
"bytes": 86,
|
| 345 |
+
"sha256": "9301bfc92623e4a8b2589e01d7ca98aac917152544b83562b23628bf4cfe414f"
|
| 346 |
+
},
|
| 347 |
+
"source/src/vimeml/deployment/bundle.py": {
|
| 348 |
+
"bytes": 7978,
|
| 349 |
+
"sha256": "4f66f215e576ea1267971da0f49d995f49b09417920cbbf9e159e2d1c8083043"
|
| 350 |
+
},
|
| 351 |
+
"source/src/vimeml/deployment/cli.py": {
|
| 352 |
+
"bytes": 6394,
|
| 353 |
+
"sha256": "55d65451e04721c3c05a131b9c422f2e7c1835d6340cc8b76c4936243521dd6a"
|
| 354 |
+
},
|
| 355 |
+
"source/src/vimeml/deployment/coreml.py": {
|
| 356 |
+
"bytes": 8328,
|
| 357 |
+
"sha256": "8281456e241e32ed79f9223d63f5c476e02b97b263723be9ad46c0a75435ee52"
|
| 358 |
+
},
|
| 359 |
+
"source/src/vimeml/deployment/graph.py": {
|
| 360 |
+
"bytes": 2306,
|
| 361 |
+
"sha256": "e2474a97e4006c4e1fe14552b11874d08c52fa217b41c9d0ab0dbab7b0a79a67"
|
| 362 |
+
},
|
| 363 |
+
"source/src/vimeml/deployment/validation.py": {
|
| 364 |
+
"bytes": 15542,
|
| 365 |
+
"sha256": "9e5d526dbd8e9be72f9d8782ac402623007226ee9e1ca14f8ce005a52a994c95"
|
| 366 |
+
},
|
| 367 |
+
"source/src/vimeml/review/__init__.py": {
|
| 368 |
+
"bytes": 32,
|
| 369 |
+
"sha256": "6422f9e2042a114155c7caf2721c1f6bd8e5de4d153009703af1281f2a1c76c3"
|
| 370 |
+
},
|
| 371 |
+
"source/src/vimeml/review/approve.py": {
|
| 372 |
+
"bytes": 3982,
|
| 373 |
+
"sha256": "b81ca9f1dcbe1b8e36f189723e81f2a3d44e9ef51f5a1c6f9ad0ce96a9b00536"
|
| 374 |
+
},
|
| 375 |
+
"source/src/vimeml/review/multi_key.py": {
|
| 376 |
+
"bytes": 8932,
|
| 377 |
+
"sha256": "e21ebd1e94159d17c26234191f2f1d1ee95e542c54a9762fe0a5717a73812e4a"
|
| 378 |
+
},
|
| 379 |
+
"source/src/vimeml/review/prepare.py": {
|
| 380 |
+
"bytes": 27338,
|
| 381 |
+
"sha256": "968209bb52d010c75066d2296a93bf27b30d264e614927d5e72bbe7c0a0b9323"
|
| 382 |
+
},
|
| 383 |
+
"source/src/vimeml/review/run.py": {
|
| 384 |
+
"bytes": 27866,
|
| 385 |
+
"sha256": "8507f1850e5b8af416108ff20b4283637d03fa267add33548674dedd7445b036"
|
| 386 |
+
},
|
| 387 |
+
"source/src/vimeml/tokenizer/__init__.py": {
|
| 388 |
+
"bytes": 35,
|
| 389 |
+
"sha256": "77c08158b861bafd5e902c886a0878a08a4afea25a5277dd33be60ae219ff624"
|
| 390 |
+
},
|
| 391 |
+
"source/src/vimeml/tokenizer/encode.py": {
|
| 392 |
+
"bytes": 9961,
|
| 393 |
+
"sha256": "92bdbdda6fa80f4dbb975f8882c021d8c7c0f9017f669c89dfae31dc2eecaa69"
|
| 394 |
+
},
|
| 395 |
+
"source/src/vimeml/tokenizer/encode_parallel.py": {
|
| 396 |
+
"bytes": 21649,
|
| 397 |
+
"sha256": "c194cb241d40b49669515f68f44278b55bcfbae210756f220b375cdee22ab009"
|
| 398 |
+
},
|
| 399 |
+
"source/src/vimeml/tokenizer/monitor.py": {
|
| 400 |
+
"bytes": 4352,
|
| 401 |
+
"sha256": "184a02f06f477a6037368ad2c2f43a32299fef83d009d851083e452ce91cf7d9"
|
| 402 |
+
},
|
| 403 |
+
"source/src/vimeml/tokenizer/native_train.py": {
|
| 404 |
+
"bytes": 387,
|
| 405 |
+
"sha256": "f42ef20a1e2b4aaa2bc6c04a2357b3c0375bb20a6055b49225318d08760ab01a"
|
| 406 |
+
},
|
| 407 |
+
"source/src/vimeml/tokenizer/store.py": {
|
| 408 |
+
"bytes": 3243,
|
| 409 |
+
"sha256": "53b285db5bfff0127281c8a35acc1beba8f5dfee1c6ae05e46923e91f9befd91"
|
| 410 |
+
},
|
| 411 |
+
"source/src/vimeml/tokenizer/train.py": {
|
| 412 |
+
"bytes": 21332,
|
| 413 |
+
"sha256": "81c218f4185345e443a5bfe1f80da024ad1260b6e3653ceb52938824cd60d752"
|
| 414 |
+
},
|
| 415 |
+
"source/src/vimeml/tools/__init__.py": {
|
| 416 |
+
"bytes": 31,
|
| 417 |
+
"sha256": "0a0511ce3c52639d6a3b0a1f030162d003bb930a2a7c795cc5f15fa68bdcb6b7"
|
| 418 |
+
},
|
| 419 |
+
"source/src/vimeml/tools/check_corpus.py": {
|
| 420 |
+
"bytes": 3242,
|
| 421 |
+
"sha256": "770f251e80a34626b3b36a193c9fd9ebaa3f4c78885382cef6cb060db7b3d762"
|
| 422 |
+
},
|
| 423 |
+
"source/src/vimeml/tools/inspect_data.py": {
|
| 424 |
+
"bytes": 4402,
|
| 425 |
+
"sha256": "5f180d035a6e73d3931959d1ae9a2eece8442390a59e522d0e908285205eb6c1"
|
| 426 |
+
},
|
| 427 |
+
"source/src/vimeml/tools/phrase_demo.html": {
|
| 428 |
+
"bytes": 9275,
|
| 429 |
+
"sha256": "c298c93b65c6c81782d5a4edea52d72e58d78a1db6c28412e15e338d97f409b5"
|
| 430 |
+
},
|
| 431 |
+
"source/src/vimeml/tools/phrase_demo.py": {
|
| 432 |
+
"bytes": 11017,
|
| 433 |
+
"sha256": "07023e63ece7f683038d0a823bac49722619940a0b1a387a989696effaaea16c"
|
| 434 |
+
},
|
| 435 |
+
"source/src/vimeml/training/__init__.py": {
|
| 436 |
+
"bytes": 64,
|
| 437 |
+
"sha256": "30be98c6d0dc0b68bb12915c37cb84d97cc3c47bc1c0734e45435ac033a02180"
|
| 438 |
+
},
|
| 439 |
+
"source/src/vimeml/training/check_data.py": {
|
| 440 |
+
"bytes": 7618,
|
| 441 |
+
"sha256": "c2530ba10df54c190211f59d1756f36de4792a4344dc78d14b88305e16a2f4be"
|
| 442 |
+
},
|
| 443 |
+
"source/src/vimeml/training/data.py": {
|
| 444 |
+
"bytes": 16536,
|
| 445 |
+
"sha256": "1627a4db9bb3c179977dc25e08b9443e84c0a966ff8416c3e5872c456b5b3ae3"
|
| 446 |
+
},
|
| 447 |
+
"source/src/vimeml/training/evaluate_ime.py": {
|
| 448 |
+
"bytes": 18317,
|
| 449 |
+
"sha256": "9a36b75893f58f61228ad7a6bbb2a34b52aaf312ca6675383580964500d639cd"
|
| 450 |
+
},
|
| 451 |
+
"source/src/vimeml/training/infer.py": {
|
| 452 |
+
"bytes": 8545,
|
| 453 |
+
"sha256": "7a093392ed15377c54bd1842cfbf32c6ab0257f3e956a81e84e41ad4624a9e9c"
|
| 454 |
+
},
|
| 455 |
+
"source/src/vimeml/training/model.py": {
|
| 456 |
+
"bytes": 4652,
|
| 457 |
+
"sha256": "dde6a0f8d7bd2d3a76e48fb503c22296da4c1156f976125bdb773d902bc7e07e"
|
| 458 |
+
},
|
| 459 |
+
"source/src/vimeml/training/train.py": {
|
| 460 |
+
"bytes": 25943,
|
| 461 |
+
"sha256": "dd34aa271f9a62af55aa877fc4090a1db0001cdce656faadd37304524eb59c5b"
|
| 462 |
+
},
|
| 463 |
+
"source/templates/huggingface/infer.py": {
|
| 464 |
+
"bytes": 1528,
|
| 465 |
+
"sha256": "8ed8d241d349a4e88840dd841da9db3191ec9f0db84c8f8165a951fa84720621"
|
| 466 |
+
},
|
| 467 |
+
"source/templates/huggingface/README.md": {
|
| 468 |
+
"bytes": 10512,
|
| 469 |
+
"sha256": "169add32b203da3142840133dc27456a63a576baecb5f9a9273d923464a1fcff"
|
| 470 |
+
},
|
| 471 |
+
"source/templates/huggingface/verify_release.py": {
|
| 472 |
+
"bytes": 2997,
|
| 473 |
+
"sha256": "80dd64ae4dac2eddbe864a2d2c4f429cf8b0bb6317b8eaf962fd378e11449b90"
|
| 474 |
+
},
|
| 475 |
+
"verify_release.py": {
|
| 476 |
+
"bytes": 2997,
|
| 477 |
+
"sha256": "80dd64ae4dac2eddbe864a2d2c4f429cf8b0bb6317b8eaf962fd378e11449b90"
|
| 478 |
+
}
|
| 479 |
+
},
|
| 480 |
+
"policy": "Local preparation only. No training, conversion, compression, device access or upload."
|
| 481 |
+
}
|
SHA256SUMS.txt
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
189b1af95d661151e054cea10c91b3d754e4de4d3fecfb074c1fb29476f7167b LICENSE
|
| 2 |
+
366194211cc7db2f7de4f82471796b543f829e4c646a984758f2a5d589556f70 README.md
|
| 3 |
+
9a1394b38c9f68911b1fa90ad06a371757fa069837bf9c24177c02761684fc24 RELEASE.json
|
| 4 |
+
a9d516233fa57aaadd09477e2e909760972ff49b5577919f8a441c489f5c2245 coreml/ios18-int8-block32/manifest.json
|
| 5 |
+
22e80193abc7672bbcf2a3fc214a186ae6e64d76c1e1b42ead38fef5a003cd37 coreml/ios18-int8-block32/model.mlpackage/Data/com.apple.CoreML/model.mlmodel
|
| 6 |
+
d3a063455371e624cf208fb6ed76fc9ac6addd8c2f87eaebf4653649f85b8109 coreml/ios18-int8-block32/model.mlpackage/Data/com.apple.CoreML/weights/weight.bin
|
| 7 |
+
31b13734848024036806cbd5bacf405eddba6c4451e5659b25f714ffe1766ee5 coreml/ios18-int8-block32/model.mlpackage/Manifest.json
|
| 8 |
+
d0fe405a4f68c3e5f94541834ab9f60cf0937b4f2fd6c50d25737e6ab828ad0e evaluation/summary.json
|
| 9 |
+
8ed8d241d349a4e88840dd841da9db3191ec9f0db84c8f8165a951fa84720621 infer.py
|
| 10 |
+
8950524f2f3a0373f3a0ebbcde79a8feaa54949ed926830c287b384306adf9ca inference/config.json
|
| 11 |
+
4284cdc5491513cc817633081677b363b14f59c0b4ffb78cdf7fcfb221f71b3c inference/manifest.json
|
| 12 |
+
c7ebf3672d46cfc75d12013c34f35fb7ac9eac613f29f3454be0cb0e991854dc inference/token-manifest.json
|
| 13 |
+
d9f1ba1e456ce72dd9c06a62b12e804cf14090c30179e6078cd51d03063b2982 inference/tokenizer.model
|
| 14 |
+
1cdac16913068bfdcfa94b139ecb34d945d0e9483a863373a6dca4397e3cd355 inference/weights.pt
|
| 15 |
+
189b1af95d661151e054cea10c91b3d754e4de4d3fecfb074c1fb29476f7167b source/LICENSE
|
| 16 |
+
5184082e7c857b4ab965d3c5b7366a0d5b56d98cdb5e40511dda6d0c2e298290 source/README.md
|
| 17 |
+
67e3bf5c3166c9c5fa847ec515c44dd41dfebee56134265df2c5b13bec14ad9a source/configs/corpus-parallel.toml
|
| 18 |
+
49f06564931dc4be63f76cdde8cd3be78ddeb81a45cbada768e0a0ca8191a49d source/configs/corpus-sharded.toml
|
| 19 |
+
46d0b4eba6293a2fa2e7ef16d9132c6320e9d2da80921d60aa939e90e35dc222 source/configs/ime-eval-v1.json
|
| 20 |
+
61c475fba63964b540e55be39d70e786886c059ce58fee94465517f648f021fe source/configs/ime-homophones.json
|
| 21 |
+
e701173b553617086ad2ab679313423eabb19e89d9f51fd31b321336584652ea source/configs/inference-prompts.json
|
| 22 |
+
e8baa76da3e223bcb3b333f96994ef4e86eeecb62cea18503eb8f7ad9c4a74cf source/configs/loader.toml
|
| 23 |
+
b51e101d6a4bc34c4a375439191e4adbd63d511ccc62b49c4d5b758decee17ed source/configs/phrase-demo-prompts.json
|
| 24 |
+
28396838808e5745c4d2251e90e095d2a2e816033526bcb154d1c74c98dfe9b5 source/configs/tokenizer.toml
|
| 25 |
+
2d386dd8efe0ffd0da6df319226daf7bab8948b1bcb2abc7afb59c45d98d28b3 source/configs/train-smoke.toml
|
| 26 |
+
44ba93246d406d5187c496ad2cf23d1533e6f581a8d6dc6f7fff03fca22b8323 source/configs/train-v1.toml
|
| 27 |
+
0fac5689cead9021745847b2753294a9a4d95c002a61762f7f25254db2a26489 source/requirements.txt
|
| 28 |
+
34a2a24d14c0e8b20c44dafab720075cbc23261a7fdbe71091dff12200e7fc24 source/scripts/benchmarks/evaluate.py
|
| 29 |
+
a28fc24da1f8cbb6972b49dc0223361e16c7b093872d92df6bd52aabd00bd54a source/scripts/benchmarks/evaluate_ajimee.py
|
| 30 |
+
d328ff258e4a8fa83e51be099f5fa8fbf480f2d377579c475c355f9f01263bf6 source/scripts/benchmarks/export_cached_development.py
|
| 31 |
+
de9866c56cd846073a3a3a82b1553ab737ccb911001d17de71839865057d0293 source/scripts/benchmarks/generate.py
|
| 32 |
+
3b3b4192535a035bbf57e3f51f1fb16a0647b1a3fc060a179b7ae9fb1127cc41 source/scripts/benchmarks/generate_development.py
|
| 33 |
+
64dbd0fcee7e294bd290bbf9f2057e81656ede4e0b328cdae710360da24716b3 source/scripts/benchmarks/hybrid.py
|
| 34 |
+
3935e16a81c389c5a3dd74da6da38732ff32b668ea3c6d0484c52f017657706a source/scripts/benchmarks/prepare_ajimee.py
|
| 35 |
+
0e4d753adf6cf97cc19b975e4f35d3cea41a4f519782f6b8eeea3309260486df source/scripts/corpus/build.py
|
| 36 |
+
dd6639d55b9aecdbf46d20fec98ab78422ff53ad14ec5a4a39d6a43e824cd0d6 source/scripts/corpus/merge.py
|
| 37 |
+
f8181f1b055661a1097d2bf80654ac59af4cf6a8b74afecb8f44b40e3d94d4f8 source/scripts/corpus/preprocess.py
|
| 38 |
+
e3e12fd3373119539eb3ed23eaccbc1457cafa7a22ae444dd4b187c118d883ce source/scripts/deployment/ane_output_probe.py
|
| 39 |
+
9a0761dbd3ece9b730ed0e52010ef965a8415b4320188c31e1863ab0c874d2fd source/scripts/deployment/compare_quantization.py
|
| 40 |
+
2aa26fb2f2b59a630cc9cafb7eb684f237c44c780c1ec820badbbd07d8f2bf41 source/scripts/deployment/compute_plan.py
|
| 41 |
+
7f321ab43b41acd4765045a93edc5c3ec874dcb741541a3f7460d13f8c27f50e source/scripts/deployment/coreml.py
|
| 42 |
+
28c67b5b30c3ad93a46703dad62236b2cd81ec5478ebf2cd9974e7b336001871 source/scripts/deployment/coreml_ane.py
|
| 43 |
+
61b290658385ee40325263be24b1a1dffdc18fe5bc494dd02a1bf93bf301b986 source/scripts/deployment/coreml_conservative.py
|
| 44 |
+
65db41ee70efb5409738ece23eb41750e695f1746e42b85314198d72710fa7a7 source/scripts/deployment/package_handoff.py
|
| 45 |
+
1228adeb409e3cf095aa7890390307b9cd518c535fc23365f5a8ffc01b144448 source/scripts/deployment/package_ios.py
|
| 46 |
+
0857bab4b1dcf81ec8b1ae5e680672cf512d5547aa3246c1e2a7ad7bfc0b79e5 source/scripts/deployment/summarize_keyboard_trace.py
|
| 47 |
+
a798a4478ba907f0b4c88246c90d865063fa5c7c02f10456e7faceea7a7966ba source/scripts/deployment/summarize_memory.py
|
| 48 |
+
bbd7f36ed4682bcdcb5e4c5d87b42733106dbaebf6f949fcd60cd498dc059274 source/scripts/publishing/hub.py
|
| 49 |
+
994c690a95f8d13d15a1ab1671185c8e2744537f48d667c176f9a3079b3630e9 source/scripts/publishing/prepare_hf.py
|
| 50 |
+
555b275e74482c597a26b3cbc23ffb1648e636801bc5ddeccf7c25df176414d0 source/scripts/review/approve.py
|
| 51 |
+
77578100f9aaae50cabac68a85996dcf02479179f6d17fbf30368ea7aa70ab5f source/scripts/review/prepare.py
|
| 52 |
+
d18a127f4a08b84ac03a398f3c96c935a0b6275fe0e7b1af2f3e3d4d92ec49b1 source/scripts/review/run.py
|
| 53 |
+
702ba0084944c8db433f1d12f64e6933659965a9a125434cce80f916f63c6f47 source/scripts/review/run_multi_key.py
|
| 54 |
+
46af106351c8835ba0e001295c4d2122c8c629d799c913feb8292d2e83100670 source/scripts/tokenizer/encode.py
|
| 55 |
+
1001c67f565711d91c59335b342ab1a3e3fdb40f7f5642a8a49ce9ac46a4823d source/scripts/tokenizer/train.py
|
| 56 |
+
231f867355c0cd2806e0ee20378c9671443309f2716db9dbf1426fda6bbe9eb6 source/scripts/tools/check_corpus.py
|
| 57 |
+
fd5a05f0c74e4d3bd95097a37be009422ec348c3fd3e36f1ca12740c02309760 source/scripts/tools/inspect_data.py
|
| 58 |
+
09d81377f63d9c967e444ffdaaec83a7228de8109c4492a5175b46a8590387bc source/scripts/tools/phrase_demo.py
|
| 59 |
+
fce755bfd04595f95d6a021c5d2533599d3463542239da198d65e4c26a716e0a source/scripts/training/check_data.py
|
| 60 |
+
81729525388462eb93ede97f917f0f6eae1ef6518c35d169e19dc745f37ffa4d source/scripts/training/evaluate_ime.py
|
| 61 |
+
6f409f7761d543e65d5f4c8886c8f59e0929b4b299977a8439bd0d13623755f4 source/scripts/training/infer.py
|
| 62 |
+
56b5781f98b3440d23d1516d830e83356db3a0b04c9aab134368c2ef9cefb91c source/scripts/training/train.py
|
| 63 |
+
db40a3f34315dcd409f0b22d8633c569f71f6807841fb2551a9ca423869ca149 source/scripts/training/train_wandb.py
|
| 64 |
+
ff0f42adee5b707f35ea0ba1307e65d8a2f632a55c3281c8f446211032f0fbc1 source/src/vimeml/__init__.py
|
| 65 |
+
03a0b8a9e43ef3ecf56189a86fe7e33d9633d4a766edf02583e911aef9bde581 source/src/vimeml/benchmarks/__init__.py
|
| 66 |
+
4916651168f3f883161ebbbc24db5e1ae5b1bc4cd6abf8c7b83560ef960406cb source/src/vimeml/benchmarks/ajimee.py
|
| 67 |
+
d74e8f9e888c115c6a9ce27f5b08ea40efb332c087d94e372d4c33364b2dc2d4 source/src/vimeml/benchmarks/development.py
|
| 68 |
+
867cd2f41b49043dd985e7f05e788f3f83a0ac47a4d0d9b2d6306dcd0c96b02a source/src/vimeml/benchmarks/evaluate.py
|
| 69 |
+
459a8c0d1bb4f8ffba57e92ee2c8bb3f5278c3e4a1a5bcc5dfda48a21bde3716 source/src/vimeml/benchmarks/evaluate_ajimee.py
|
| 70 |
+
9a468c23ea3ebf02f1184b1742cbe11a025f2a0d7ae57e0ee2e54468de72a1d7 source/src/vimeml/benchmarks/generate.py
|
| 71 |
+
71267f445ac92736f1dabf03c3e77193e9f2a1323f23fa1bc060aff4fbe4ea7e source/src/vimeml/benchmarks/hybrid.py
|
| 72 |
+
55cdd3f899dd7ad156f8987cf2ba2bbbc76a95dfaba33a319058b4d01e2f9947 source/src/vimeml/corpus/__init__.py
|
| 73 |
+
895b6894c4b85e72c8655cf6b42e21d51b51736d649ec2adb6841e033f4ac1f9 source/src/vimeml/corpus/build.py
|
| 74 |
+
86d655d2d715fcb2f73269c1ffbfc9e87d9080a1baaf389f88e30de6022fdc19 source/src/vimeml/data/__init__.py
|
| 75 |
+
ba62919c8084d24cb3f41c451e970b5448e7b0f5407340c28cca0b220d387395 source/src/vimeml/data/annotations.py
|
| 76 |
+
d7d63e1ea9a2f9da9fe92ff2773b792c7ca89911b2d7058a2709fcbbc443081e source/src/vimeml/data/build.py
|
| 77 |
+
ee88adbb74d5a03f591231484928becf0a62557c85702efddd214c9bc8a2354f source/src/vimeml/data/clean.py
|
| 78 |
+
d2e943aae1e2942076b1db8430067e048fcdc71d46761bb329f7fa460e843280 source/src/vimeml/data/corpus_export.py
|
| 79 |
+
c196a78e5096e659eb8c536602e009c98de346bd82084c29f9384e526055f6f6 source/src/vimeml/data/corpus_parts.py
|
| 80 |
+
43cb87845d17e52261675073b010269c53e4c79a8e5e16237d2627c9e07116e6 source/src/vimeml/data/merge_parts.py
|
| 81 |
+
600dc56899dfa6ac2eda639cf79f6ad5e789642b99d6c68569262f593bfc3642 source/src/vimeml/data/merge_parts_fast.py
|
| 82 |
+
433a93f18809aa1b11a13c8e63edce2a73864140fbaf4a4bcff0c7ab475be164 source/src/vimeml/data/preprocess_part.py
|
| 83 |
+
837017b0282f62ed68c9a47c69da3ed12fe39b74e7f88bc3ae16113f55b679b6 source/src/vimeml/data/readers.py
|
| 84 |
+
9834f4867e126f229e86a7fc5b7481f4c803c05d00a21966a78ec293095b0f8c source/src/vimeml/data/segment.py
|
| 85 |
+
9301bfc92623e4a8b2589e01d7ca98aac917152544b83562b23628bf4cfe414f source/src/vimeml/deployment/__init__.py
|
| 86 |
+
4f66f215e576ea1267971da0f49d995f49b09417920cbbf9e159e2d1c8083043 source/src/vimeml/deployment/bundle.py
|
| 87 |
+
55d65451e04721c3c05a131b9c422f2e7c1835d6340cc8b76c4936243521dd6a source/src/vimeml/deployment/cli.py
|
| 88 |
+
8281456e241e32ed79f9223d63f5c476e02b97b263723be9ad46c0a75435ee52 source/src/vimeml/deployment/coreml.py
|
| 89 |
+
e2474a97e4006c4e1fe14552b11874d08c52fa217b41c9d0ab0dbab7b0a79a67 source/src/vimeml/deployment/graph.py
|
| 90 |
+
9e5d526dbd8e9be72f9d8782ac402623007226ee9e1ca14f8ce005a52a994c95 source/src/vimeml/deployment/validation.py
|
| 91 |
+
6422f9e2042a114155c7caf2721c1f6bd8e5de4d153009703af1281f2a1c76c3 source/src/vimeml/review/__init__.py
|
| 92 |
+
b81ca9f1dcbe1b8e36f189723e81f2a3d44e9ef51f5a1c6f9ad0ce96a9b00536 source/src/vimeml/review/approve.py
|
| 93 |
+
e21ebd1e94159d17c26234191f2f1d1ee95e542c54a9762fe0a5717a73812e4a source/src/vimeml/review/multi_key.py
|
| 94 |
+
968209bb52d010c75066d2296a93bf27b30d264e614927d5e72bbe7c0a0b9323 source/src/vimeml/review/prepare.py
|
| 95 |
+
8507f1850e5b8af416108ff20b4283637d03fa267add33548674dedd7445b036 source/src/vimeml/review/run.py
|
| 96 |
+
77c08158b861bafd5e902c886a0878a08a4afea25a5277dd33be60ae219ff624 source/src/vimeml/tokenizer/__init__.py
|
| 97 |
+
92bdbdda6fa80f4dbb975f8882c021d8c7c0f9017f669c89dfae31dc2eecaa69 source/src/vimeml/tokenizer/encode.py
|
| 98 |
+
c194cb241d40b49669515f68f44278b55bcfbae210756f220b375cdee22ab009 source/src/vimeml/tokenizer/encode_parallel.py
|
| 99 |
+
184a02f06f477a6037368ad2c2f43a32299fef83d009d851083e452ce91cf7d9 source/src/vimeml/tokenizer/monitor.py
|
| 100 |
+
f42ef20a1e2b4aaa2bc6c04a2357b3c0375bb20a6055b49225318d08760ab01a source/src/vimeml/tokenizer/native_train.py
|
| 101 |
+
53b285db5bfff0127281c8a35acc1beba8f5dfee1c6ae05e46923e91f9befd91 source/src/vimeml/tokenizer/store.py
|
| 102 |
+
81c218f4185345e443a5bfe1f80da024ad1260b6e3653ceb52938824cd60d752 source/src/vimeml/tokenizer/train.py
|
| 103 |
+
0a0511ce3c52639d6a3b0a1f030162d003bb930a2a7c795cc5f15fa68bdcb6b7 source/src/vimeml/tools/__init__.py
|
| 104 |
+
770f251e80a34626b3b36a193c9fd9ebaa3f4c78885382cef6cb060db7b3d762 source/src/vimeml/tools/check_corpus.py
|
| 105 |
+
5f180d035a6e73d3931959d1ae9a2eece8442390a59e522d0e908285205eb6c1 source/src/vimeml/tools/inspect_data.py
|
| 106 |
+
c298c93b65c6c81782d5a4edea52d72e58d78a1db6c28412e15e338d97f409b5 source/src/vimeml/tools/phrase_demo.html
|
| 107 |
+
07023e63ece7f683038d0a823bac49722619940a0b1a387a989696effaaea16c source/src/vimeml/tools/phrase_demo.py
|
| 108 |
+
30be98c6d0dc0b68bb12915c37cb84d97cc3c47bc1c0734e45435ac033a02180 source/src/vimeml/training/__init__.py
|
| 109 |
+
c2530ba10df54c190211f59d1756f36de4792a4344dc78d14b88305e16a2f4be source/src/vimeml/training/check_data.py
|
| 110 |
+
1627a4db9bb3c179977dc25e08b9443e84c0a966ff8416c3e5872c456b5b3ae3 source/src/vimeml/training/data.py
|
| 111 |
+
9a36b75893f58f61228ad7a6bbb2a34b52aaf312ca6675383580964500d639cd source/src/vimeml/training/evaluate_ime.py
|
| 112 |
+
7a093392ed15377c54bd1842cfbf32c6ab0257f3e956a81e84e41ad4624a9e9c source/src/vimeml/training/infer.py
|
| 113 |
+
dde6a0f8d7bd2d3a76e48fb503c22296da4c1156f976125bdb773d902bc7e07e source/src/vimeml/training/model.py
|
| 114 |
+
dd34aa271f9a62af55aa877fc4090a1db0001cdce656faadd37304524eb59c5b source/src/vimeml/training/train.py
|
| 115 |
+
169add32b203da3142840133dc27456a63a576baecb5f9a9273d923464a1fcff source/templates/huggingface/README.md
|
| 116 |
+
8ed8d241d349a4e88840dd841da9db3191ec9f0db84c8f8165a951fa84720621 source/templates/huggingface/infer.py
|
| 117 |
+
80dd64ae4dac2eddbe864a2d2c4f429cf8b0bb6317b8eaf962fd378e11449b90 source/templates/huggingface/verify_release.py
|
| 118 |
+
80dd64ae4dac2eddbe864a2d2c4f429cf8b0bb6317b8eaf962fd378e11449b90 verify_release.py
|
coreml/ios18-int8-block32/manifest.json
ADDED
|
@@ -0,0 +1,491 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"format": "vimeml_coreml_v1",
|
| 3 |
+
"status": "complete",
|
| 4 |
+
"kind": "linear8_fp32_compute",
|
| 5 |
+
"minimum_ios": 18,
|
| 6 |
+
"bundle": {
|
| 7 |
+
"checkpoint_sha256": "93b6139aa05031df02038efcaf26788bc9916712919f3d2a4c4f398615cef75b",
|
| 8 |
+
"tokenizer_sha256": "d9f1ba1e456ce72dd9c06a62b12e804cf14090c30179e6078cd51d03063b2982",
|
| 9 |
+
"bundle_manifest_sha256": "4284cdc5491513cc817633081677b363b14f59c0b4ffb78cdf7fcfb221f71b3c",
|
| 10 |
+
"model": {
|
| 11 |
+
"vocab_size": 16384,
|
| 12 |
+
"context_length": 128,
|
| 13 |
+
"d_model": 256,
|
| 14 |
+
"n_heads": 4,
|
| 15 |
+
"n_layers": 4,
|
| 16 |
+
"d_ff": 1024,
|
| 17 |
+
"dropout": 0.0
|
| 18 |
+
},
|
| 19 |
+
"precision": "fp32",
|
| 20 |
+
"device": "cpu",
|
| 21 |
+
"environment": {
|
| 22 |
+
"python": "3.11.17",
|
| 23 |
+
"platform": "macOS-27.2-arm64-arm-64bit",
|
| 24 |
+
"machine": "arm64",
|
| 25 |
+
"packages": {
|
| 26 |
+
"torch": "2.7.1",
|
| 27 |
+
"numpy": "2.3.5",
|
| 28 |
+
"sentencepiece": "0.2.1",
|
| 29 |
+
"coremltools": "9.0"
|
| 30 |
+
}
|
| 31 |
+
}
|
| 32 |
+
},
|
| 33 |
+
"interface": {
|
| 34 |
+
"input_ids": "int32 [1,T], 1<=T<=128; right PAD only",
|
| 35 |
+
"logits": "float32 [1,T,16384]; FP32 computation; no softmax"
|
| 36 |
+
},
|
| 37 |
+
"source_manifest_sha256": "f5591ad1512b931a3a20765eb2218771f68e49699a3d23601e0cc0566d9c6d9d",
|
| 38 |
+
"fp16_alignment_sha256": "6bfead3f03f53f3e43780427515b3c5f12e6713845fd9f3a459df95aa23f800a",
|
| 39 |
+
"conversion_script_sha256": "4674f9d9e298562c8f517636674bf973532b8fc6ddc802aae8ca2aa939642912",
|
| 40 |
+
"precision_policy": {
|
| 41 |
+
"source_recipe": "fp16_weights_fp32_compute_preserve_positions_qkv_v1",
|
| 42 |
+
"computation": "FP32; token embedding gather is FP16 then cast to FP32"
|
| 43 |
+
},
|
| 44 |
+
"compression": {
|
| 45 |
+
"method": "linear",
|
| 46 |
+
"bits": 8,
|
| 47 |
+
"group_size": 16,
|
| 48 |
+
"block_size": 32,
|
| 49 |
+
"weight_threshold": 2048,
|
| 50 |
+
"selection": {
|
| 51 |
+
"policy": "linear_weights_and_named_embedding_tables_v1",
|
| 52 |
+
"selected_constants": [
|
| 53 |
+
{
|
| 54 |
+
"name": "model_position_embedding_weight",
|
| 55 |
+
"shape": [
|
| 56 |
+
128,
|
| 57 |
+
256
|
| 58 |
+
],
|
| 59 |
+
"dtype": "float32",
|
| 60 |
+
"elements": 32768,
|
| 61 |
+
"consumers": [
|
| 62 |
+
{
|
| 63 |
+
"name": "op_143",
|
| 64 |
+
"type": "gather",
|
| 65 |
+
"inputs": {
|
| 66 |
+
"x": "model_position_embedding_weight"
|
| 67 |
+
}
|
| 68 |
+
}
|
| 69 |
+
]
|
| 70 |
+
},
|
| 71 |
+
{
|
| 72 |
+
"name": "model_blocks_0_attention_qkv_weight",
|
| 73 |
+
"shape": [
|
| 74 |
+
768,
|
| 75 |
+
256
|
| 76 |
+
],
|
| 77 |
+
"dtype": "float32",
|
| 78 |
+
"elements": 196608,
|
| 79 |
+
"consumers": [
|
| 80 |
+
{
|
| 81 |
+
"name": "linear_0",
|
| 82 |
+
"type": "linear",
|
| 83 |
+
"inputs": {
|
| 84 |
+
"weight": "model_blocks_0_attention_qkv_weight"
|
| 85 |
+
}
|
| 86 |
+
}
|
| 87 |
+
]
|
| 88 |
+
},
|
| 89 |
+
{
|
| 90 |
+
"name": "model_blocks_1_attention_qkv_weight",
|
| 91 |
+
"shape": [
|
| 92 |
+
768,
|
| 93 |
+
256
|
| 94 |
+
],
|
| 95 |
+
"dtype": "float32",
|
| 96 |
+
"elements": 196608,
|
| 97 |
+
"consumers": [
|
| 98 |
+
{
|
| 99 |
+
"name": "linear_4",
|
| 100 |
+
"type": "linear",
|
| 101 |
+
"inputs": {
|
| 102 |
+
"weight": "model_blocks_1_attention_qkv_weight"
|
| 103 |
+
}
|
| 104 |
+
}
|
| 105 |
+
]
|
| 106 |
+
},
|
| 107 |
+
{
|
| 108 |
+
"name": "model_blocks_2_attention_qkv_weight",
|
| 109 |
+
"shape": [
|
| 110 |
+
768,
|
| 111 |
+
256
|
| 112 |
+
],
|
| 113 |
+
"dtype": "float32",
|
| 114 |
+
"elements": 196608,
|
| 115 |
+
"consumers": [
|
| 116 |
+
{
|
| 117 |
+
"name": "linear_8",
|
| 118 |
+
"type": "linear",
|
| 119 |
+
"inputs": {
|
| 120 |
+
"weight": "model_blocks_2_attention_qkv_weight"
|
| 121 |
+
}
|
| 122 |
+
}
|
| 123 |
+
]
|
| 124 |
+
},
|
| 125 |
+
{
|
| 126 |
+
"name": "model_blocks_3_attention_qkv_weight",
|
| 127 |
+
"shape": [
|
| 128 |
+
768,
|
| 129 |
+
256
|
| 130 |
+
],
|
| 131 |
+
"dtype": "float32",
|
| 132 |
+
"elements": 196608,
|
| 133 |
+
"consumers": [
|
| 134 |
+
{
|
| 135 |
+
"name": "linear_12",
|
| 136 |
+
"type": "linear",
|
| 137 |
+
"inputs": {
|
| 138 |
+
"weight": "model_blocks_3_attention_qkv_weight"
|
| 139 |
+
}
|
| 140 |
+
}
|
| 141 |
+
]
|
| 142 |
+
},
|
| 143 |
+
{
|
| 144 |
+
"name": "model_token_embedding_weight_storage_fp16",
|
| 145 |
+
"shape": [
|
| 146 |
+
16384,
|
| 147 |
+
256
|
| 148 |
+
],
|
| 149 |
+
"dtype": "float16",
|
| 150 |
+
"elements": 4194304,
|
| 151 |
+
"consumers": [
|
| 152 |
+
{
|
| 153 |
+
"name": "op_139_storage_fp16",
|
| 154 |
+
"type": "gather",
|
| 155 |
+
"inputs": {
|
| 156 |
+
"x": "model_token_embedding_weight_storage_fp16"
|
| 157 |
+
}
|
| 158 |
+
},
|
| 159 |
+
{
|
| 160 |
+
"name": "linear_16_compute_fp32",
|
| 161 |
+
"type": "linear",
|
| 162 |
+
"inputs": {
|
| 163 |
+
"weight": "model_token_embedding_weight_storage_fp16",
|
| 164 |
+
"bias": "linear_16_bias_0_storage_fp16"
|
| 165 |
+
}
|
| 166 |
+
}
|
| 167 |
+
]
|
| 168 |
+
},
|
| 169 |
+
{
|
| 170 |
+
"name": "model_blocks_0_attention_projection_weight_storage_fp16",
|
| 171 |
+
"shape": [
|
| 172 |
+
256,
|
| 173 |
+
256
|
| 174 |
+
],
|
| 175 |
+
"dtype": "float16",
|
| 176 |
+
"elements": 65536,
|
| 177 |
+
"consumers": [
|
| 178 |
+
{
|
| 179 |
+
"name": "linear_1_compute_fp32",
|
| 180 |
+
"type": "linear",
|
| 181 |
+
"inputs": {
|
| 182 |
+
"weight": "model_blocks_0_attention_projection_weight_storage_fp16"
|
| 183 |
+
}
|
| 184 |
+
}
|
| 185 |
+
]
|
| 186 |
+
},
|
| 187 |
+
{
|
| 188 |
+
"name": "model_blocks_0_ffn_0_weight_storage_fp16",
|
| 189 |
+
"shape": [
|
| 190 |
+
1024,
|
| 191 |
+
256
|
| 192 |
+
],
|
| 193 |
+
"dtype": "float16",
|
| 194 |
+
"elements": 262144,
|
| 195 |
+
"consumers": [
|
| 196 |
+
{
|
| 197 |
+
"name": "linear_2_compute_fp32",
|
| 198 |
+
"type": "linear",
|
| 199 |
+
"inputs": {
|
| 200 |
+
"weight": "model_blocks_0_ffn_0_weight_storage_fp16"
|
| 201 |
+
}
|
| 202 |
+
}
|
| 203 |
+
]
|
| 204 |
+
},
|
| 205 |
+
{
|
| 206 |
+
"name": "model_blocks_0_ffn_2_weight_storage_fp16",
|
| 207 |
+
"shape": [
|
| 208 |
+
256,
|
| 209 |
+
1024
|
| 210 |
+
],
|
| 211 |
+
"dtype": "float16",
|
| 212 |
+
"elements": 262144,
|
| 213 |
+
"consumers": [
|
| 214 |
+
{
|
| 215 |
+
"name": "linear_3_compute_fp32",
|
| 216 |
+
"type": "linear",
|
| 217 |
+
"inputs": {
|
| 218 |
+
"weight": "model_blocks_0_ffn_2_weight_storage_fp16"
|
| 219 |
+
}
|
| 220 |
+
}
|
| 221 |
+
]
|
| 222 |
+
},
|
| 223 |
+
{
|
| 224 |
+
"name": "model_blocks_1_attention_projection_weight_storage_fp16",
|
| 225 |
+
"shape": [
|
| 226 |
+
256,
|
| 227 |
+
256
|
| 228 |
+
],
|
| 229 |
+
"dtype": "float16",
|
| 230 |
+
"elements": 65536,
|
| 231 |
+
"consumers": [
|
| 232 |
+
{
|
| 233 |
+
"name": "linear_5_compute_fp32",
|
| 234 |
+
"type": "linear",
|
| 235 |
+
"inputs": {
|
| 236 |
+
"weight": "model_blocks_1_attention_projection_weight_storage_fp16"
|
| 237 |
+
}
|
| 238 |
+
}
|
| 239 |
+
]
|
| 240 |
+
},
|
| 241 |
+
{
|
| 242 |
+
"name": "model_blocks_1_ffn_0_weight_storage_fp16",
|
| 243 |
+
"shape": [
|
| 244 |
+
1024,
|
| 245 |
+
256
|
| 246 |
+
],
|
| 247 |
+
"dtype": "float16",
|
| 248 |
+
"elements": 262144,
|
| 249 |
+
"consumers": [
|
| 250 |
+
{
|
| 251 |
+
"name": "linear_6_compute_fp32",
|
| 252 |
+
"type": "linear",
|
| 253 |
+
"inputs": {
|
| 254 |
+
"weight": "model_blocks_1_ffn_0_weight_storage_fp16"
|
| 255 |
+
}
|
| 256 |
+
}
|
| 257 |
+
]
|
| 258 |
+
},
|
| 259 |
+
{
|
| 260 |
+
"name": "model_blocks_1_ffn_2_weight_storage_fp16",
|
| 261 |
+
"shape": [
|
| 262 |
+
256,
|
| 263 |
+
1024
|
| 264 |
+
],
|
| 265 |
+
"dtype": "float16",
|
| 266 |
+
"elements": 262144,
|
| 267 |
+
"consumers": [
|
| 268 |
+
{
|
| 269 |
+
"name": "linear_7_compute_fp32",
|
| 270 |
+
"type": "linear",
|
| 271 |
+
"inputs": {
|
| 272 |
+
"weight": "model_blocks_1_ffn_2_weight_storage_fp16"
|
| 273 |
+
}
|
| 274 |
+
}
|
| 275 |
+
]
|
| 276 |
+
},
|
| 277 |
+
{
|
| 278 |
+
"name": "model_blocks_2_attention_projection_weight_storage_fp16",
|
| 279 |
+
"shape": [
|
| 280 |
+
256,
|
| 281 |
+
256
|
| 282 |
+
],
|
| 283 |
+
"dtype": "float16",
|
| 284 |
+
"elements": 65536,
|
| 285 |
+
"consumers": [
|
| 286 |
+
{
|
| 287 |
+
"name": "linear_9_compute_fp32",
|
| 288 |
+
"type": "linear",
|
| 289 |
+
"inputs": {
|
| 290 |
+
"weight": "model_blocks_2_attention_projection_weight_storage_fp16"
|
| 291 |
+
}
|
| 292 |
+
}
|
| 293 |
+
]
|
| 294 |
+
},
|
| 295 |
+
{
|
| 296 |
+
"name": "model_blocks_2_ffn_0_weight_storage_fp16",
|
| 297 |
+
"shape": [
|
| 298 |
+
1024,
|
| 299 |
+
256
|
| 300 |
+
],
|
| 301 |
+
"dtype": "float16",
|
| 302 |
+
"elements": 262144,
|
| 303 |
+
"consumers": [
|
| 304 |
+
{
|
| 305 |
+
"name": "linear_10_compute_fp32",
|
| 306 |
+
"type": "linear",
|
| 307 |
+
"inputs": {
|
| 308 |
+
"weight": "model_blocks_2_ffn_0_weight_storage_fp16"
|
| 309 |
+
}
|
| 310 |
+
}
|
| 311 |
+
]
|
| 312 |
+
},
|
| 313 |
+
{
|
| 314 |
+
"name": "model_blocks_2_ffn_2_weight_storage_fp16",
|
| 315 |
+
"shape": [
|
| 316 |
+
256,
|
| 317 |
+
1024
|
| 318 |
+
],
|
| 319 |
+
"dtype": "float16",
|
| 320 |
+
"elements": 262144,
|
| 321 |
+
"consumers": [
|
| 322 |
+
{
|
| 323 |
+
"name": "linear_11_compute_fp32",
|
| 324 |
+
"type": "linear",
|
| 325 |
+
"inputs": {
|
| 326 |
+
"weight": "model_blocks_2_ffn_2_weight_storage_fp16"
|
| 327 |
+
}
|
| 328 |
+
}
|
| 329 |
+
]
|
| 330 |
+
},
|
| 331 |
+
{
|
| 332 |
+
"name": "model_blocks_3_attention_projection_weight_storage_fp16",
|
| 333 |
+
"shape": [
|
| 334 |
+
256,
|
| 335 |
+
256
|
| 336 |
+
],
|
| 337 |
+
"dtype": "float16",
|
| 338 |
+
"elements": 65536,
|
| 339 |
+
"consumers": [
|
| 340 |
+
{
|
| 341 |
+
"name": "linear_13_compute_fp32",
|
| 342 |
+
"type": "linear",
|
| 343 |
+
"inputs": {
|
| 344 |
+
"weight": "model_blocks_3_attention_projection_weight_storage_fp16"
|
| 345 |
+
}
|
| 346 |
+
}
|
| 347 |
+
]
|
| 348 |
+
},
|
| 349 |
+
{
|
| 350 |
+
"name": "model_blocks_3_ffn_0_weight_storage_fp16",
|
| 351 |
+
"shape": [
|
| 352 |
+
1024,
|
| 353 |
+
256
|
| 354 |
+
],
|
| 355 |
+
"dtype": "float16",
|
| 356 |
+
"elements": 262144,
|
| 357 |
+
"consumers": [
|
| 358 |
+
{
|
| 359 |
+
"name": "linear_14_compute_fp32",
|
| 360 |
+
"type": "linear",
|
| 361 |
+
"inputs": {
|
| 362 |
+
"weight": "model_blocks_3_ffn_0_weight_storage_fp16"
|
| 363 |
+
}
|
| 364 |
+
}
|
| 365 |
+
]
|
| 366 |
+
},
|
| 367 |
+
{
|
| 368 |
+
"name": "model_blocks_3_ffn_2_weight_storage_fp16",
|
| 369 |
+
"shape": [
|
| 370 |
+
256,
|
| 371 |
+
1024
|
| 372 |
+
],
|
| 373 |
+
"dtype": "float16",
|
| 374 |
+
"elements": 262144,
|
| 375 |
+
"consumers": [
|
| 376 |
+
{
|
| 377 |
+
"name": "linear_15_compute_fp32",
|
| 378 |
+
"type": "linear",
|
| 379 |
+
"inputs": {
|
| 380 |
+
"weight": "model_blocks_3_ffn_2_weight_storage_fp16"
|
| 381 |
+
}
|
| 382 |
+
}
|
| 383 |
+
]
|
| 384 |
+
}
|
| 385 |
+
],
|
| 386 |
+
"excluded_constants": [
|
| 387 |
+
{
|
| 388 |
+
"name": "causal_mask",
|
| 389 |
+
"shape": [
|
| 390 |
+
128,
|
| 391 |
+
128
|
| 392 |
+
],
|
| 393 |
+
"dtype": "float32",
|
| 394 |
+
"elements": 16384,
|
| 395 |
+
"consumers": [
|
| 396 |
+
{
|
| 397 |
+
"name": "op_182",
|
| 398 |
+
"type": "slice_by_index",
|
| 399 |
+
"inputs": {
|
| 400 |
+
"x": "causal_mask"
|
| 401 |
+
}
|
| 402 |
+
}
|
| 403 |
+
],
|
| 404 |
+
"reason": "Not a linear weight or named embedding parameter",
|
| 405 |
+
"nonfinite_elements": 8128
|
| 406 |
+
},
|
| 407 |
+
{
|
| 408 |
+
"name": "linear_16_bias_0_storage_fp16",
|
| 409 |
+
"shape": [
|
| 410 |
+
16384
|
| 411 |
+
],
|
| 412 |
+
"dtype": "float16",
|
| 413 |
+
"elements": 16384,
|
| 414 |
+
"consumers": [
|
| 415 |
+
{
|
| 416 |
+
"name": "linear_16_compute_fp32",
|
| 417 |
+
"type": "linear",
|
| 418 |
+
"inputs": {
|
| 419 |
+
"weight": "model_token_embedding_weight_storage_fp16",
|
| 420 |
+
"bias": "linear_16_bias_0_storage_fp16"
|
| 421 |
+
}
|
| 422 |
+
}
|
| 423 |
+
],
|
| 424 |
+
"reason": "Not a linear weight or named embedding parameter",
|
| 425 |
+
"nonfinite_elements": 0
|
| 426 |
+
}
|
| 427 |
+
],
|
| 428 |
+
"selected_elements": 7372800
|
| 429 |
+
},
|
| 430 |
+
"scope": "Eligible learned matrices, including FP32 QKV; structural constants/masks unchanged; no activation quantization or retraining."
|
| 431 |
+
},
|
| 432 |
+
"environment": {
|
| 433 |
+
"python": "3.11.17",
|
| 434 |
+
"platform": "macOS-27.2-arm64-arm-64bit",
|
| 435 |
+
"machine": "arm64",
|
| 436 |
+
"packages": {
|
| 437 |
+
"torch": "2.7.1",
|
| 438 |
+
"numpy": "2.3.5",
|
| 439 |
+
"sentencepiece": "0.2.1",
|
| 440 |
+
"coremltools": "9.0"
|
| 441 |
+
}
|
| 442 |
+
},
|
| 443 |
+
"spec": {
|
| 444 |
+
"specification_version": 9,
|
| 445 |
+
"operations": {
|
| 446 |
+
"const": 153,
|
| 447 |
+
"constexpr_blockwise_shift_scale": 18,
|
| 448 |
+
"shape": 1,
|
| 449 |
+
"gather": 3,
|
| 450 |
+
"range_1d": 1,
|
| 451 |
+
"greater_equal": 6,
|
| 452 |
+
"add": 19,
|
| 453 |
+
"select": 6,
|
| 454 |
+
"cast": 1,
|
| 455 |
+
"layer_norm": 9,
|
| 456 |
+
"linear": 17,
|
| 457 |
+
"reshape": 8,
|
| 458 |
+
"transpose": 8,
|
| 459 |
+
"split": 4,
|
| 460 |
+
"squeeze": 12,
|
| 461 |
+
"matmul": 8,
|
| 462 |
+
"mul": 4,
|
| 463 |
+
"concat": 2,
|
| 464 |
+
"slice_by_index": 2,
|
| 465 |
+
"softmax": 4,
|
| 466 |
+
"gelu": 4
|
| 467 |
+
},
|
| 468 |
+
"inputs": [
|
| 469 |
+
"input_ids"
|
| 470 |
+
],
|
| 471 |
+
"outputs": [
|
| 472 |
+
"logits"
|
| 473 |
+
]
|
| 474 |
+
},
|
| 475 |
+
"package_files": {
|
| 476 |
+
"Data/com.apple.CoreML/model.mlmodel": {
|
| 477 |
+
"bytes": 46400,
|
| 478 |
+
"sha256": "22e80193abc7672bbcf2a3fc214a186ae6e64d76c1e1b42ead38fef5a003cd37"
|
| 479 |
+
},
|
| 480 |
+
"Data/com.apple.CoreML/weights/weight.bin": {
|
| 481 |
+
"bytes": 8030784,
|
| 482 |
+
"sha256": "d3a063455371e624cf208fb6ed76fc9ac6addd8c2f87eaebf4653649f85b8109"
|
| 483 |
+
},
|
| 484 |
+
"Manifest.json": {
|
| 485 |
+
"bytes": 617,
|
| 486 |
+
"sha256": "31b13734848024036806cbd5bacf405eddba6c4451e5659b25f714ffe1766ee5"
|
| 487 |
+
}
|
| 488 |
+
},
|
| 489 |
+
"package_bytes": 8077801,
|
| 490 |
+
"note": "Logical file bytes, not compiled size, IPA size or resident memory. Inspect weight.bin and const/constexpr ops for tied-weight duplication."
|
| 491 |
+
}
|
coreml/ios18-int8-block32/model.mlpackage/Data/com.apple.CoreML/model.mlmodel
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:22e80193abc7672bbcf2a3fc214a186ae6e64d76c1e1b42ead38fef5a003cd37
|
| 3 |
+
size 46400
|
coreml/ios18-int8-block32/model.mlpackage/Data/com.apple.CoreML/weights/weight.bin
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d3a063455371e624cf208fb6ed76fc9ac6addd8c2f87eaebf4653649f85b8109
|
| 3 |
+
size 8030784
|
coreml/ios18-int8-block32/model.mlpackage/Manifest.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"fileFormatVersion": "1.0.0",
|
| 3 |
+
"itemInfoEntries": {
|
| 4 |
+
"B5BC0804-8142-444E-8A75-43E553098EA8": {
|
| 5 |
+
"author": "com.apple.CoreML",
|
| 6 |
+
"description": "CoreML Model Weights",
|
| 7 |
+
"name": "weights",
|
| 8 |
+
"path": "com.apple.CoreML/weights"
|
| 9 |
+
},
|
| 10 |
+
"C4D1258E-24AB-4839-B8C6-61581D74BA25": {
|
| 11 |
+
"author": "com.apple.CoreML",
|
| 12 |
+
"description": "CoreML Model Specification",
|
| 13 |
+
"name": "model.mlmodel",
|
| 14 |
+
"path": "com.apple.CoreML/model.mlmodel"
|
| 15 |
+
}
|
| 16 |
+
},
|
| 17 |
+
"rootModelIdentifier": "C4D1258E-24AB-4839-B8C6-61581D74BA25"
|
| 18 |
+
}
|
evaluation/summary.json
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"format": "vimeml_public_evaluation_v1",
|
| 3 |
+
"bundle_manifest_sha256": "4284cdc5491513cc817633081677b363b14f59c0b4ffb78cdf7fcfb221f71b3c",
|
| 4 |
+
"coreml_manifest_sha256": "a9d516233fa57aaadd09477e2e909760972ff49b5577919f8a441c489f5c2245",
|
| 5 |
+
"training": {
|
| 6 |
+
"prediction_targets": 573295237,
|
| 7 |
+
"data_passes": 1.0,
|
| 8 |
+
"full_validation": {
|
| 9 |
+
"loss": 4.541570895102848,
|
| 10 |
+
"prediction_pairs": 5890326,
|
| 11 |
+
"perplexity": 93.83809420004854
|
| 12 |
+
},
|
| 13 |
+
"test_used_for_selection": false
|
| 14 |
+
},
|
| 15 |
+
"ranking": {
|
| 16 |
+
"dev": {
|
| 17 |
+
"original_order": {
|
| 18 |
+
"cases": 137,
|
| 19 |
+
"top1_correct": 111,
|
| 20 |
+
"top1_accuracy": 0.8102189781021898,
|
| 21 |
+
"top5_correct": 130,
|
| 22 |
+
"top5_accuracy": 0.948905109489051,
|
| 23 |
+
"candidate_pool_covered": 136,
|
| 24 |
+
"candidate_pool_recall": 0.9927007299270073,
|
| 25 |
+
"covered_top1_accuracy": 0.8161764705882353,
|
| 26 |
+
"mean_min_cer": 0.04746998743349109,
|
| 27 |
+
"mrr": 0.8745925911071898,
|
| 28 |
+
"corrected_vs_azookey": 0,
|
| 29 |
+
"regressed_vs_azookey": 0,
|
| 30 |
+
"fallback_cases": 0
|
| 31 |
+
},
|
| 32 |
+
"fp32_lm": {
|
| 33 |
+
"cases": 137,
|
| 34 |
+
"top1_correct": 122,
|
| 35 |
+
"top1_accuracy": 0.8905109489051095,
|
| 36 |
+
"top5_correct": 134,
|
| 37 |
+
"top5_accuracy": 0.9781021897810219,
|
| 38 |
+
"candidate_pool_covered": 136,
|
| 39 |
+
"candidate_pool_recall": 0.9927007299270073,
|
| 40 |
+
"covered_top1_accuracy": 0.8970588235294118,
|
| 41 |
+
"mean_min_cer": 0.03045798483754688,
|
| 42 |
+
"mrr": 0.935349322210636,
|
| 43 |
+
"corrected_vs_azookey": 15,
|
| 44 |
+
"regressed_vs_azookey": 4,
|
| 45 |
+
"fallback_cases": 0
|
| 46 |
+
},
|
| 47 |
+
"int8_lm": {
|
| 48 |
+
"cases": 137,
|
| 49 |
+
"top1_correct": 122,
|
| 50 |
+
"top1_accuracy": 0.8905109489051095,
|
| 51 |
+
"top5_correct": 134,
|
| 52 |
+
"top5_accuracy": 0.9781021897810219,
|
| 53 |
+
"candidate_pool_covered": 136,
|
| 54 |
+
"candidate_pool_recall": 0.9927007299270073,
|
| 55 |
+
"covered_top1_accuracy": 0.8970588235294118,
|
| 56 |
+
"mean_min_cer": 0.03045798483754688,
|
| 57 |
+
"mrr": 0.935349322210636,
|
| 58 |
+
"corrected_vs_azookey": 15,
|
| 59 |
+
"regressed_vs_azookey": 4,
|
| 60 |
+
"fallback_cases": 0
|
| 61 |
+
},
|
| 62 |
+
"windows_fp32_comparison": {
|
| 63 |
+
"order_changed_cases": 119,
|
| 64 |
+
"top1_changed_cases": 0,
|
| 65 |
+
"max_score_sum_abs": 1.9853296279907227,
|
| 66 |
+
"mean_score_sum_abs": 0.20199488408841776
|
| 67 |
+
},
|
| 68 |
+
"original_report_comparison_baseline": "conservative Core ML",
|
| 69 |
+
"original_report_comparison": {
|
| 70 |
+
"order_changed_cases": 118,
|
| 71 |
+
"top1_changed_cases": 0,
|
| 72 |
+
"max_score_sum_abs": 1.994759202003479,
|
| 73 |
+
"mean_score_sum_abs": 0.2013680215637894
|
| 74 |
+
},
|
| 75 |
+
"benchmark_source_sha256": "a945f2117570530ef73b1dd4ef53b9dc69b07fa69ac98a6d67c9268b540eafa8",
|
| 76 |
+
"candidate_export_sha256": "ab192509dce1cb4f4b20273e623f7bfd4237b1c3691950438e6921b8a510ae21"
|
| 77 |
+
},
|
| 78 |
+
"ajimee": {
|
| 79 |
+
"original_order": {
|
| 80 |
+
"cases": 200,
|
| 81 |
+
"top1_correct": 87,
|
| 82 |
+
"top1_accuracy": 0.435,
|
| 83 |
+
"top5_correct": 143,
|
| 84 |
+
"top5_accuracy": 0.715,
|
| 85 |
+
"candidate_pool_covered": 162,
|
| 86 |
+
"candidate_pool_recall": 0.81,
|
| 87 |
+
"covered_top1_accuracy": 0.5370370370370371,
|
| 88 |
+
"mean_min_cer": 0.0821630611981915,
|
| 89 |
+
"mrr": 0.554232017982018,
|
| 90 |
+
"corrected_vs_azookey": 0,
|
| 91 |
+
"regressed_vs_azookey": 0,
|
| 92 |
+
"fallback_cases": 0
|
| 93 |
+
},
|
| 94 |
+
"fp32_lm": {
|
| 95 |
+
"cases": 200,
|
| 96 |
+
"top1_correct": 124,
|
| 97 |
+
"top1_accuracy": 0.62,
|
| 98 |
+
"top5_correct": 151,
|
| 99 |
+
"top5_accuracy": 0.755,
|
| 100 |
+
"candidate_pool_covered": 162,
|
| 101 |
+
"candidate_pool_recall": 0.81,
|
| 102 |
+
"covered_top1_accuracy": 0.7654320987654321,
|
| 103 |
+
"mean_min_cer": 0.05657040945427151,
|
| 104 |
+
"mrr": 0.684061974789916,
|
| 105 |
+
"corrected_vs_azookey": 48,
|
| 106 |
+
"regressed_vs_azookey": 11,
|
| 107 |
+
"fallback_cases": 0
|
| 108 |
+
},
|
| 109 |
+
"int8_lm": {
|
| 110 |
+
"cases": 200,
|
| 111 |
+
"top1_correct": 124,
|
| 112 |
+
"top1_accuracy": 0.62,
|
| 113 |
+
"top5_correct": 151,
|
| 114 |
+
"top5_accuracy": 0.755,
|
| 115 |
+
"candidate_pool_covered": 162,
|
| 116 |
+
"candidate_pool_recall": 0.81,
|
| 117 |
+
"covered_top1_accuracy": 0.7654320987654321,
|
| 118 |
+
"mean_min_cer": 0.05657040945427151,
|
| 119 |
+
"mrr": 0.6841512605042016,
|
| 120 |
+
"corrected_vs_azookey": 48,
|
| 121 |
+
"regressed_vs_azookey": 11,
|
| 122 |
+
"fallback_cases": 0
|
| 123 |
+
},
|
| 124 |
+
"windows_fp32_comparison": {
|
| 125 |
+
"order_changed_cases": 163,
|
| 126 |
+
"top1_changed_cases": 2,
|
| 127 |
+
"max_score_sum_abs": 2.6928324103355408,
|
| 128 |
+
"mean_score_sum_abs": 0.33380034679328247
|
| 129 |
+
},
|
| 130 |
+
"original_report_comparison_baseline": "Windows FP32",
|
| 131 |
+
"original_report_comparison": {
|
| 132 |
+
"order_changed_cases": 163,
|
| 133 |
+
"top1_changed_cases": 2,
|
| 134 |
+
"max_score_sum_abs": 2.6928324103355408,
|
| 135 |
+
"mean_score_sum_abs": 0.33380034679328247
|
| 136 |
+
},
|
| 137 |
+
"benchmark_source_sha256": "e9eb668fd6aa14b1e26436f429b5550108af0a1dfd443b8cea0bcb3ab3028fca",
|
| 138 |
+
"candidate_export_sha256": "6b532af2e7b1536ded98e9d75cbba4fd7338b4204987fc4dafb16df7edfdf223"
|
| 139 |
+
}
|
| 140 |
+
},
|
| 141 |
+
"alignment": {
|
| 142 |
+
"strict_passed": false,
|
| 143 |
+
"max_logit_abs": 3.6601905822753906,
|
| 144 |
+
"invariants": {
|
| 145 |
+
"right_pad": {
|
| 146 |
+
"max_abs": 2.8133392333984375e-05,
|
| 147 |
+
"mean_abs": 2.5544544911072975e-06,
|
| 148 |
+
"rmse": 3.420821628891477e-06,
|
| 149 |
+
"outside_tolerance": 0,
|
| 150 |
+
"values": 114688
|
| 151 |
+
},
|
| 152 |
+
"causal": {
|
| 153 |
+
"max_abs": 0.0,
|
| 154 |
+
"mean_abs": 0.0,
|
| 155 |
+
"rmse": 0.0,
|
| 156 |
+
"outside_tolerance": 0,
|
| 157 |
+
"values": 262144
|
| 158 |
+
}
|
| 159 |
+
}
|
| 160 |
+
},
|
| 161 |
+
"distribution": {
|
| 162 |
+
"original_report": {
|
| 163 |
+
"model": "artifacts/deployment/tiny-ja-v1-conservative-int8-b32-v1",
|
| 164 |
+
"compute_units": "CPU_ONLY",
|
| 165 |
+
"benchmark_text": {
|
| 166 |
+
"kl_coreml": {
|
| 167 |
+
"mean": 0.005891128288349137,
|
| 168 |
+
"max": 0.025890197604894638
|
| 169 |
+
},
|
| 170 |
+
"kl_simulated": {
|
| 171 |
+
"mean": 0.005977873008232564,
|
| 172 |
+
"max": 0.028363749384880066
|
| 173 |
+
},
|
| 174 |
+
"nll_fp32": {
|
| 175 |
+
"mean": 5.566977231502533,
|
| 176 |
+
"max": 8.531479835510254
|
| 177 |
+
},
|
| 178 |
+
"nll_coreml": {
|
| 179 |
+
"mean": 5.572893209457398,
|
| 180 |
+
"max": 8.633211135864258
|
| 181 |
+
},
|
| 182 |
+
"top1_agreement": {
|
| 183 |
+
"mean": 0.943656535744667,
|
| 184 |
+
"max": 1.0
|
| 185 |
+
},
|
| 186 |
+
"max_logprob_diff": {
|
| 187 |
+
"mean": 0.9077084493637085,
|
| 188 |
+
"max": 3.5512266159057617
|
| 189 |
+
}
|
| 190 |
+
},
|
| 191 |
+
"random_tokens": {
|
| 192 |
+
"kl_coreml": {
|
| 193 |
+
"mean": 0.015501508116722107,
|
| 194 |
+
"max": 0.01807662844657898
|
| 195 |
+
},
|
| 196 |
+
"kl_simulated": {
|
| 197 |
+
"mean": 0.015804098173975944,
|
| 198 |
+
"max": 0.01901794597506523
|
| 199 |
+
},
|
| 200 |
+
"nll_fp32": {
|
| 201 |
+
"mean": 11.800455474853516,
|
| 202 |
+
"max": 12.100545883178711
|
| 203 |
+
},
|
| 204 |
+
"nll_coreml": {
|
| 205 |
+
"mean": 11.795885848999024,
|
| 206 |
+
"max": 12.123295783996582
|
| 207 |
+
},
|
| 208 |
+
"top1_agreement": {
|
| 209 |
+
"mean": 0.9140625,
|
| 210 |
+
"max": 0.9296875
|
| 211 |
+
},
|
| 212 |
+
"max_logprob_diff": {
|
| 213 |
+
"mean": 2.206966495513916,
|
| 214 |
+
"max": 2.564694404602051
|
| 215 |
+
}
|
| 216 |
+
}
|
| 217 |
+
},
|
| 218 |
+
"aggregation": "Mean of per-example position means; not corpus token-weighted.",
|
| 219 |
+
"content_token_limit": 127,
|
| 220 |
+
"truncation_count_recorded": false,
|
| 221 |
+
"original_report_has_full_identity_metadata": false
|
| 222 |
+
},
|
| 223 |
+
"source_reports_sha256": {
|
| 224 |
+
"outputs/deployment/conservative-int8-b32-dev-v1/metrics.json": "839e220c3024ec9798c921fb39d8862c5f874889c9dd9c2066cb339894658329",
|
| 225 |
+
"outputs/deployment/conservative-int8-b32-dev-v1/scores.jsonl": "f00a6b56b96e6be1db3ba7c58abe53bc91e7614c2f7f7959c27b0a8cce8db936",
|
| 226 |
+
"outputs/ime-eval/tiny-ja-v1-dev-v2-scores/manifest.json": "16bbd3b5b921e54896cfdca880d77c78fedd76b2aa8956fbaaa4c45bd4a4030e",
|
| 227 |
+
"outputs/ime-eval/tiny-ja-v1-dev-v2-scores/scores.jsonl": "2710b88428b5f73c6aeac5d45d442fa0d9bca1e038db2928c6059be993f3cfcb",
|
| 228 |
+
"outputs/deployment/conservative-dev-v3/metrics.json": "387d80e1b52a2c8dbcbb2196471ae548ae869b1e3f259dc1ee972c592e6b4863",
|
| 229 |
+
"outputs/deployment/conservative-dev-v3/scores.jsonl": "bb4fa9f52a074144a3cb432777ec6c94ad07637cdecd5b2126ad5d64a4e6a1d2",
|
| 230 |
+
"outputs/deployment/conservative-int8-b32-ajimee-v1/metrics.json": "3b59e396173328c78e8164f809da24764474685a2bd35765457fac5df644aac5",
|
| 231 |
+
"outputs/deployment/conservative-int8-b32-ajimee-v1/scores.jsonl": "9daf557818ab0aef12fb74e68b8cd4ae502806650d3d7e0cd23eeb2e1499e89e",
|
| 232 |
+
"outputs/ime-eval/tiny-ja-v1-ajimee/metrics.json": "219e15ec8ee54b09b455bd14ce60ab99bff239510ab9df344b69d2afc4b21196",
|
| 233 |
+
"outputs/ime-eval/tiny-ja-v1-ajimee/scores.jsonl": "247b29b59285551acaf73fabf9bee79c9617360623329e6bb60deb2d33ee7ddf",
|
| 234 |
+
"outputs/deployment/conservative-int8-b32-alignment-v1/alignment.json": "6773fafbd84e27dc1c349234fe601898e9f2af56ec5e2dcc6a32b12fbe14d018",
|
| 235 |
+
"outputs/deployment/conservative-int8-b32-distribution-v1/report.json": "6970eafdbb0d8e8b075d5b38b241cfa8fa46777961106ac32714755950722852",
|
| 236 |
+
"artifacts/models/tiny-ja-v1/summary.json": "4d9417b3bb8702b025b1ce4962d38ea36ad6d52928d19267dccdcaed3bf6c022"
|
| 237 |
+
},
|
| 238 |
+
"scope": "Offline fixed pools and saved Mac observations; not app-wide accuracy or a Windows Core ML runtime rerun."
|
| 239 |
+
}
|
infer.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Read-only FP32 inference using the included, fingerprint-checked VimeML source."""
|
| 2 |
+
import argparse
|
| 3 |
+
import json
|
| 4 |
+
import sys
|
| 5 |
+
from pathlib import Path
|
| 6 |
+
|
| 7 |
+
ROOT = Path(__file__).resolve().parent
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
def main():
|
| 11 |
+
parser = argparse.ArgumentParser(description=__doc__)
|
| 12 |
+
parser.add_argument('--prompt', default='今日は雨が降っているので、')
|
| 13 |
+
parser.add_argument('--candidate', action='append', help='Rerank these strings after --prompt; repeat for each candidate.')
|
| 14 |
+
parser.add_argument('--max-new-tokens', type=int, default=8)
|
| 15 |
+
parser.add_argument('--threads', type=int, default=4)
|
| 16 |
+
args = parser.parse_args()
|
| 17 |
+
if args.threads < 1 or args.max_new_tokens < 1:
|
| 18 |
+
parser.error('threads and max-new-tokens must be positive.')
|
| 19 |
+
# The wrapper has no model math or scoring changes. Original code lives in source/.
|
| 20 |
+
sys.path.insert(0, str(ROOT / 'source/src'))
|
| 21 |
+
import torch
|
| 22 |
+
from vimeml.deployment.bundle import BundleLM
|
| 23 |
+
from vimeml.training.evaluate_ime import score_candidates
|
| 24 |
+
torch.set_num_threads(args.threads)
|
| 25 |
+
lm = BundleLM(ROOT / 'inference')
|
| 26 |
+
if args.candidate:
|
| 27 |
+
result = score_candidates(lm, args.prompt, args.candidate)
|
| 28 |
+
result['ranked_candidates'] = sorted(result['candidates'],
|
| 29 |
+
key=lambda item: item['log_probability_sum'], reverse=True)
|
| 30 |
+
else:
|
| 31 |
+
result = lm.generate(args.prompt, max_new_tokens=args.max_new_tokens, temperature=0)
|
| 32 |
+
print(json.dumps(result, ensure_ascii=False, indent=2))
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
if __name__ == '__main__':
|
| 36 |
+
main()
|
inference/config.json
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"vocab_size": 16384,
|
| 3 |
+
"context_length": 128,
|
| 4 |
+
"d_model": 256,
|
| 5 |
+
"n_heads": 4,
|
| 6 |
+
"n_layers": 4,
|
| 7 |
+
"d_ff": 1024,
|
| 8 |
+
"dropout": 0.0
|
| 9 |
+
}
|
inference/manifest.json
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"format": "vimeml_inference_bundle_v1",
|
| 3 |
+
"status": "complete",
|
| 4 |
+
"parameter_count": 7386624,
|
| 5 |
+
"precision": "fp32",
|
| 6 |
+
"special_ids": {
|
| 7 |
+
"pad": 0,
|
| 8 |
+
"unk": 1,
|
| 9 |
+
"bos": 2,
|
| 10 |
+
"eos": 3
|
| 11 |
+
},
|
| 12 |
+
"tied_lm_head": true,
|
| 13 |
+
"checkpoint_sha256": "93b6139aa05031df02038efcaf26788bc9916712919f3d2a4c4f398615cef75b",
|
| 14 |
+
"checkpoint_step": 196853,
|
| 15 |
+
"training_signatures": {
|
| 16 |
+
"tokens": "c7ebf3672d46cfc75d12013c34f35fb7ac9eac613f29f3454be0cb0e991854dc",
|
| 17 |
+
"windows": "4cdc90177a3fac335ad39434156f54ad20aa143190700950a122d914fd05d617",
|
| 18 |
+
"training_code": {
|
| 19 |
+
"train.py": "dd34aa271f9a62af55aa877fc4090a1db0001cdce656faadd37304524eb59c5b",
|
| 20 |
+
"model.py": "dde6a0f8d7bd2d3a76e48fb503c22296da4c1156f976125bdb773d902bc7e07e",
|
| 21 |
+
"data.py": "1627a4db9bb3c179977dc25e08b9443e84c0a966ff8416c3e5872c456b5b3ae3"
|
| 22 |
+
}
|
| 23 |
+
},
|
| 24 |
+
"source_fingerprints": {
|
| 25 |
+
"src/vimeml/training/model.py": {
|
| 26 |
+
"sha256": "dde6a0f8d7bd2d3a76e48fb503c22296da4c1156f976125bdb773d902bc7e07e",
|
| 27 |
+
"lf_sha256": "dde6a0f8d7bd2d3a76e48fb503c22296da4c1156f976125bdb773d902bc7e07e"
|
| 28 |
+
},
|
| 29 |
+
"src/vimeml/training/data.py": {
|
| 30 |
+
"sha256": "1627a4db9bb3c179977dc25e08b9443e84c0a966ff8416c3e5872c456b5b3ae3",
|
| 31 |
+
"lf_sha256": "1627a4db9bb3c179977dc25e08b9443e84c0a966ff8416c3e5872c456b5b3ae3"
|
| 32 |
+
},
|
| 33 |
+
"src/vimeml/training/train.py": {
|
| 34 |
+
"sha256": "dd34aa271f9a62af55aa877fc4090a1db0001cdce656faadd37304524eb59c5b",
|
| 35 |
+
"lf_sha256": "dd34aa271f9a62af55aa877fc4090a1db0001cdce656faadd37304524eb59c5b"
|
| 36 |
+
},
|
| 37 |
+
"src/vimeml/training/infer.py": {
|
| 38 |
+
"sha256": "7a093392ed15377c54bd1842cfbf32c6ab0257f3e956a81e84e41ad4624a9e9c",
|
| 39 |
+
"lf_sha256": "7a093392ed15377c54bd1842cfbf32c6ab0257f3e956a81e84e41ad4624a9e9c"
|
| 40 |
+
},
|
| 41 |
+
"src/vimeml/training/evaluate_ime.py": {
|
| 42 |
+
"sha256": "9a36b75893f58f61228ad7a6bbb2a34b52aaf312ca6675383580964500d639cd",
|
| 43 |
+
"lf_sha256": "9a36b75893f58f61228ad7a6bbb2a34b52aaf312ca6675383580964500d639cd"
|
| 44 |
+
},
|
| 45 |
+
"src/vimeml/benchmarks/evaluate_ajimee.py": {
|
| 46 |
+
"sha256": "459a8c0d1bb4f8ffba57e92ee2c8bb3f5278c3e4a1a5bcc5dfda48a21bde3716",
|
| 47 |
+
"lf_sha256": "459a8c0d1bb4f8ffba57e92ee2c8bb3f5278c3e4a1a5bcc5dfda48a21bde3716"
|
| 48 |
+
},
|
| 49 |
+
"src/vimeml/tools/phrase_demo.py": {
|
| 50 |
+
"sha256": "07023e63ece7f683038d0a823bac49722619940a0b1a387a989696effaaea16c",
|
| 51 |
+
"lf_sha256": "07023e63ece7f683038d0a823bac49722619940a0b1a387a989696effaaea16c"
|
| 52 |
+
},
|
| 53 |
+
"src/vimeml/deployment/__init__.py": {
|
| 54 |
+
"sha256": "9301bfc92623e4a8b2589e01d7ca98aac917152544b83562b23628bf4cfe414f",
|
| 55 |
+
"lf_sha256": "9301bfc92623e4a8b2589e01d7ca98aac917152544b83562b23628bf4cfe414f"
|
| 56 |
+
},
|
| 57 |
+
"src/vimeml/deployment/bundle.py": {
|
| 58 |
+
"sha256": "4f66f215e576ea1267971da0f49d995f49b09417920cbbf9e159e2d1c8083043",
|
| 59 |
+
"lf_sha256": "4f66f215e576ea1267971da0f49d995f49b09417920cbbf9e159e2d1c8083043"
|
| 60 |
+
},
|
| 61 |
+
"src/vimeml/deployment/cli.py": {
|
| 62 |
+
"sha256": "55d65451e04721c3c05a131b9c422f2e7c1835d6340cc8b76c4936243521dd6a",
|
| 63 |
+
"lf_sha256": "55d65451e04721c3c05a131b9c422f2e7c1835d6340cc8b76c4936243521dd6a"
|
| 64 |
+
},
|
| 65 |
+
"src/vimeml/deployment/coreml.py": {
|
| 66 |
+
"sha256": "8281456e241e32ed79f9223d63f5c476e02b97b263723be9ad46c0a75435ee52",
|
| 67 |
+
"lf_sha256": "8281456e241e32ed79f9223d63f5c476e02b97b263723be9ad46c0a75435ee52"
|
| 68 |
+
},
|
| 69 |
+
"src/vimeml/deployment/graph.py": {
|
| 70 |
+
"sha256": "e2474a97e4006c4e1fe14552b11874d08c52fa217b41c9d0ab0dbab7b0a79a67",
|
| 71 |
+
"lf_sha256": "e2474a97e4006c4e1fe14552b11874d08c52fa217b41c9d0ab0dbab7b0a79a67"
|
| 72 |
+
},
|
| 73 |
+
"src/vimeml/deployment/validation.py": {
|
| 74 |
+
"sha256": "9e5d526dbd8e9be72f9d8782ac402623007226ee9e1ca14f8ce005a52a994c95",
|
| 75 |
+
"lf_sha256": "9e5d526dbd8e9be72f9d8782ac402623007226ee9e1ca14f8ce005a52a994c95"
|
| 76 |
+
}
|
| 77 |
+
},
|
| 78 |
+
"environment": {
|
| 79 |
+
"python": "3.13.5",
|
| 80 |
+
"platform": "Windows-11-10.0.26300-SP0",
|
| 81 |
+
"machine": "AMD64",
|
| 82 |
+
"packages": {
|
| 83 |
+
"torch": "2.10.0+cu128",
|
| 84 |
+
"numpy": "2.5.3",
|
| 85 |
+
"sentencepiece": "0.2.1",
|
| 86 |
+
"coremltools": null
|
| 87 |
+
}
|
| 88 |
+
},
|
| 89 |
+
"files": {
|
| 90 |
+
"config.json": {
|
| 91 |
+
"bytes": 145,
|
| 92 |
+
"sha256": "8950524f2f3a0373f3a0ebbcde79a8feaa54949ed926830c287b384306adf9ca"
|
| 93 |
+
},
|
| 94 |
+
"token-manifest.json": {
|
| 95 |
+
"bytes": 6208,
|
| 96 |
+
"sha256": "c7ebf3672d46cfc75d12013c34f35fb7ac9eac613f29f3454be0cb0e991854dc"
|
| 97 |
+
},
|
| 98 |
+
"tokenizer.model": {
|
| 99 |
+
"bytes": 284118,
|
| 100 |
+
"sha256": "d9f1ba1e456ce72dd9c06a62b12e804cf14090c30179e6078cd51d03063b2982"
|
| 101 |
+
},
|
| 102 |
+
"weights.pt": {
|
| 103 |
+
"bytes": 29562119,
|
| 104 |
+
"sha256": "1cdac16913068bfdcfa94b139ecb34d945d0e9483a863373a6dca4397e3cd355"
|
| 105 |
+
}
|
| 106 |
+
},
|
| 107 |
+
"policy": "Weights only; no optimizer, RNG or training state. LM-only contextual suffix logP sum; no extra EOS; no KV cache."
|
| 108 |
+
}
|
inference/token-manifest.json
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"status": "complete",
|
| 3 |
+
"format": "vimeml_sentence_tokens_v1",
|
| 4 |
+
"vocab_size": 16384,
|
| 5 |
+
"token_dtype": "uint16_le",
|
| 6 |
+
"offset_dtype": "uint64_le",
|
| 7 |
+
"offset_unit": "tokens",
|
| 8 |
+
"special_ids": {
|
| 9 |
+
"pad": 0,
|
| 10 |
+
"unk": 1,
|
| 11 |
+
"bos": 2,
|
| 12 |
+
"eos": 3
|
| 13 |
+
},
|
| 14 |
+
"sentencepiece_version": "0.2.1",
|
| 15 |
+
"splits": {
|
| 16 |
+
"train": {
|
| 17 |
+
"sentences": 25185368,
|
| 18 |
+
"stored_tokens": 598480605,
|
| 19 |
+
"content_tokens": 548109869,
|
| 20 |
+
"characters": 1080952698,
|
| 21 |
+
"prediction_pairs": 573295237,
|
| 22 |
+
"max_sequence_tokens": 590,
|
| 23 |
+
"primary_sources": {
|
| 24 |
+
"fineweb": 24938228,
|
| 25 |
+
"tatoeba": 247140
|
| 26 |
+
},
|
| 27 |
+
"file_bytes": {
|
| 28 |
+
"tokens.bin": 1196961210,
|
| 29 |
+
"offsets.bin": 201482952,
|
| 30 |
+
"rows.bin": 201482944,
|
| 31 |
+
"sources.bin": 25185368
|
| 32 |
+
}
|
| 33 |
+
},
|
| 34 |
+
"validation": {
|
| 35 |
+
"sentences": 260337,
|
| 36 |
+
"stored_tokens": 6150663,
|
| 37 |
+
"content_tokens": 5629989,
|
| 38 |
+
"characters": 11110489,
|
| 39 |
+
"prediction_pairs": 5890326,
|
| 40 |
+
"max_sequence_tokens": 439,
|
| 41 |
+
"primary_sources": {
|
| 42 |
+
"fineweb": 257916,
|
| 43 |
+
"tatoeba": 2421
|
| 44 |
+
},
|
| 45 |
+
"file_bytes": {
|
| 46 |
+
"tokens.bin": 12301326,
|
| 47 |
+
"offsets.bin": 2082704,
|
| 48 |
+
"rows.bin": 2082696,
|
| 49 |
+
"sources.bin": 260337
|
| 50 |
+
}
|
| 51 |
+
},
|
| 52 |
+
"test": {
|
| 53 |
+
"sentences": 267298,
|
| 54 |
+
"stored_tokens": 6258211,
|
| 55 |
+
"content_tokens": 5723615,
|
| 56 |
+
"characters": 11296824,
|
| 57 |
+
"prediction_pairs": 5990913,
|
| 58 |
+
"max_sequence_tokens": 497,
|
| 59 |
+
"primary_sources": {
|
| 60 |
+
"fineweb": 264698,
|
| 61 |
+
"tatoeba": 2600
|
| 62 |
+
},
|
| 63 |
+
"file_bytes": {
|
| 64 |
+
"tokens.bin": 12516422,
|
| 65 |
+
"offsets.bin": 2138392,
|
| 66 |
+
"rows.bin": 2138384,
|
| 67 |
+
"sources.bin": 267298
|
| 68 |
+
}
|
| 69 |
+
}
|
| 70 |
+
},
|
| 71 |
+
"source_ids": {
|
| 72 |
+
"fineweb": 0,
|
| 73 |
+
"tatoeba": 1
|
| 74 |
+
},
|
| 75 |
+
"sequence_policy": "Each sequence is BOS + complete encoded sentence + EOS; no truncation or concatenation.",
|
| 76 |
+
"prediction_policy": "x=s[:-1], y=s[1:]; sentence boundaries remain separate.",
|
| 77 |
+
"provenance_policy": "Index equals zero-based corpus JSONL/TXT row. rows.bin stores uint64 little-endian byte positions in the source JSONL; sources.bin stores uint8 primary source IDs. Full original metadata stays in corpus JSONL.",
|
| 78 |
+
"corpus_dir": "D:\\Sources\\VimeML\\outputs\\corpus-fast-v1",
|
| 79 |
+
"tokenizer_dir": "D:\\Sources\\VimeML\\artifacts\\tokenizers\\ja-unigram-16k-v1",
|
| 80 |
+
"input_sha256": {
|
| 81 |
+
"D:\\Sources\\VimeML\\outputs\\corpus-fast-v1\\train.txt": "9c1b4585adaf0518dc0275e7f8086e967db26f9797fb571e1ff481aeadf2ff8f",
|
| 82 |
+
"D:\\Sources\\VimeML\\outputs\\corpus-fast-v1\\train.jsonl": "0c8bb3db59cd820db6315c63cd1b7adc92e7afcb7e8bc82ee39820f1e3d7ea21",
|
| 83 |
+
"D:\\Sources\\VimeML\\outputs\\corpus-fast-v1\\validation.txt": "f188bea10a8b464dd385d8e0aa310225de07e2a0a170e90ce63503c150bf4cdd",
|
| 84 |
+
"D:\\Sources\\VimeML\\outputs\\corpus-fast-v1\\validation.jsonl": "544773d7bd40ed22244a618db4508675109441eb69959d41a191e689fcbdfd58",
|
| 85 |
+
"D:\\Sources\\VimeML\\outputs\\corpus-fast-v1\\test.txt": "92e99a5062473a749254d90d9268ede03a804c9a8ac5806aa0a43e8b63222972",
|
| 86 |
+
"D:\\Sources\\VimeML\\outputs\\corpus-fast-v1\\test.jsonl": "28b0a0493f5c77c5ecdb768d6e023400b191d6855f5542a68a0a87a766586ef3",
|
| 87 |
+
"D:\\Sources\\VimeML\\outputs\\corpus-fast-v1\\manifest.json": "4a9d25d2a4abc6d9df8b008b49e34c060b917606c700dfa3b9f0dd4006030233",
|
| 88 |
+
"D:\\Sources\\VimeML\\outputs\\corpus-fast-v1\\stats.json": "fd7fc5077f0fdccd46591c1664735990a8f28fa8c93fa12a0e0030352ac7ec8b",
|
| 89 |
+
"D:\\Sources\\VimeML\\artifacts\\tokenizers\\ja-unigram-16k-v1\\tokenizer.model": "d9f1ba1e456ce72dd9c06a62b12e804cf14090c30179e6078cd51d03063b2982",
|
| 90 |
+
"D:\\Sources\\VimeML\\artifacts\\tokenizers\\ja-unigram-16k-v1\\manifest.json": "e88e66dee784ffa087a90e584793c2f41fb1f135499cf1bdd9eaa7cfb72ee921",
|
| 91 |
+
"D:\\Sources\\VimeML\\artifacts\\tokenizers\\ja-unigram-16k-v1\\stats.json": "9232bce676e86718940cdb11b5ad5d92b123816723ab68fa3d47212adca60ba8",
|
| 92 |
+
"D:\\Sources\\VimeML\\src\\vimeml\\tokenizer\\encode_parallel.py": "c194cb241d40b49669515f68f44278b55bcfbae210756f220b375cdee22ab009",
|
| 93 |
+
"D:\\Sources\\VimeML\\src\\vimeml\\tokenizer\\encode.py": "92bdbdda6fa80f4dbb975f8882c021d8c7c0f9017f669c89dfae31dc2eecaa69",
|
| 94 |
+
"D:\\Sources\\VimeML\\src\\vimeml\\tokenizer\\monitor.py": "c8cae279ea7faa0021b85bbc8dd2151510360a18db87982638920cc15a726b3a",
|
| 95 |
+
"D:\\Sources\\VimeML\\src\\vimeml\\tokenizer\\train.py": "3dc553d88962feb67fb919ee1f08879b2f9eac0d5b2783db7eed385505d3ee37"
|
| 96 |
+
},
|
| 97 |
+
"output_sha256": {
|
| 98 |
+
"train.tokens.bin": "5d8bafb458cdc510c0a9e9182d55d084c03cbc651eb348e387a965ac1b882834",
|
| 99 |
+
"train.offsets.bin": "8cee1724543d454e353fbd023cb40b0c0a9b2f9eb9b24b9e8ddae85afb46e762",
|
| 100 |
+
"train.rows.bin": "7cc9d8960e16d8df1c4ad1798255ade4def3bd066072439ebc3b7e8336674756",
|
| 101 |
+
"train.sources.bin": "e0e5184a6cc40fd6df0c4858cb56d79af838b07f07b86913b2a65395d325e616",
|
| 102 |
+
"validation.tokens.bin": "1bc211def7323bb620f164172a906e160c1860c1832c7d03c2de9699472f96cd",
|
| 103 |
+
"validation.offsets.bin": "e193c626736661525e2757186fb3588556d081a8019144fec0337de217dbfe1c",
|
| 104 |
+
"validation.rows.bin": "e63780d4e9b8378cee413683b6e861392dcb15a8af10308c63a8bcf68402bb79",
|
| 105 |
+
"validation.sources.bin": "dd57fbd72bf36133403751dc583943a5adf0409cf2a77bdb56ac6cc461944c34",
|
| 106 |
+
"test.tokens.bin": "ad5e5f6d5e5805bc7dbc883bbcd221df8d5699126c5a9210e86b86dad71a4e2c",
|
| 107 |
+
"test.offsets.bin": "89cdbcd19a39d0a2ff6a120aa1aeb526fc30aab03eec76b0fe50e51ca311dec3",
|
| 108 |
+
"test.rows.bin": "9653952ecabd27980f28ad7da21787b8e51046f55141a19cb21032e6de9b2faa",
|
| 109 |
+
"test.sources.bin": "473cc664829aa10e3c423389129427821b9985118febf6b276d01bd523056e37",
|
| 110 |
+
"stats.json": "563df68f55d54ed273681eb51145fd7b2cf4f2b4c1f86a053f07c666f9bc919b"
|
| 111 |
+
},
|
| 112 |
+
"corpus_quality_mode": "rules_with_approved_annotations",
|
| 113 |
+
"corpus_ready_for_lm_training": false,
|
| 114 |
+
"purpose": "Full token data for the accepted first corpus baseline; known extraction and near-duplicate limitations remain.",
|
| 115 |
+
"workers": 16,
|
| 116 |
+
"native_threads_per_worker": 1,
|
| 117 |
+
"signature": "53badf97e9290a595598f4c1cb270a118e5b92870dd406769752d119c31d963a",
|
| 118 |
+
"script_sha256": "c194cb241d40b49669515f68f44278b55bcfbae210756f220b375cdee22ab009"
|
| 119 |
+
}
|
inference/tokenizer.model
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d9f1ba1e456ce72dd9c06a62b12e804cf14090c30179e6078cd51d03063b2982
|
| 3 |
+
size 284118
|
inference/weights.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:1cdac16913068bfdcfa94b139ecb34d945d0e9483a863373a6dca4397e3cd355
|
| 3 |
+
size 29562119
|
source/LICENSE
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
GNU GENERAL PUBLIC LICENSE
|
| 2 |
+
Version 2, June 1991
|
| 3 |
+
|
| 4 |
+
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
| 5 |
+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
| 6 |
+
Everyone is permitted to copy and distribute verbatim copies
|
| 7 |
+
of this license document, but changing it is not allowed.
|
| 8 |
+
|
| 9 |
+
Preamble
|
| 10 |
+
|
| 11 |
+
The licenses for most software are designed to take away your
|
| 12 |
+
freedom to share and change it. By contrast, the GNU General Public
|
| 13 |
+
License is intended to guarantee your freedom to share and change free
|
| 14 |
+
software--to make sure the software is free for all its users. This
|
| 15 |
+
General Public License applies to most of the Free Software
|
| 16 |
+
Foundation's software and to any other program whose authors commit to
|
| 17 |
+
using it. (Some other Free Software Foundation software is covered by
|
| 18 |
+
the GNU Lesser General Public License instead.) You can apply it to
|
| 19 |
+
your programs, too.
|
| 20 |
+
|
| 21 |
+
When we speak of free software, we are referring to freedom, not
|
| 22 |
+
price. Our General Public Licenses are designed to make sure that you
|
| 23 |
+
have the freedom to distribute copies of free software (and charge for
|
| 24 |
+
this service if you wish), that you receive source code or can get it
|
| 25 |
+
if you want it, that you can change the software or use pieces of it
|
| 26 |
+
in new free programs; and that you know you can do these things.
|
| 27 |
+
|
| 28 |
+
To protect your rights, we need to make restrictions that forbid
|
| 29 |
+
anyone to deny you these rights or to ask you to surrender the rights.
|
| 30 |
+
These restrictions translate to certain responsibilities for you if you
|
| 31 |
+
distribute copies of the software, or if you modify it.
|
| 32 |
+
|
| 33 |
+
For example, if you distribute copies of such a program, whether
|
| 34 |
+
gratis or for a fee, you must give the recipients all the rights that
|
| 35 |
+
you have. You must make sure that they, too, receive or can get the
|
| 36 |
+
source code. And you must show them these terms so they know their
|
| 37 |
+
rights.
|
| 38 |
+
|
| 39 |
+
We protect your rights with two steps: (1) copyright the software, and
|
| 40 |
+
(2) offer you this license which gives you legal permission to copy,
|
| 41 |
+
distribute and/or modify the software.
|
| 42 |
+
|
| 43 |
+
Also, for each author's protection and ours, we want to make certain
|
| 44 |
+
that everyone understands that there is no warranty for this free
|
| 45 |
+
software. If the software is modified by someone else and passed on, we
|
| 46 |
+
want its recipients to know that what they have is not the original, so
|
| 47 |
+
that any problems introduced by others will not reflect on the original
|
| 48 |
+
authors' reputations.
|
| 49 |
+
|
| 50 |
+
Finally, any free program is threatened constantly by software
|
| 51 |
+
patents. We wish to avoid the danger that redistributors of a free
|
| 52 |
+
program will individually obtain patent licenses, in effect making the
|
| 53 |
+
program proprietary. To prevent this, we have made it clear that any
|
| 54 |
+
patent must be licensed for everyone's free use or not licensed at all.
|
| 55 |
+
|
| 56 |
+
The precise terms and conditions for copying, distribution and
|
| 57 |
+
modification follow.
|
| 58 |
+
|
| 59 |
+
GNU GENERAL PUBLIC LICENSE
|
| 60 |
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
| 61 |
+
|
| 62 |
+
0. This License applies to any program or other work which contains
|
| 63 |
+
a notice placed by the copyright holder saying it may be distributed
|
| 64 |
+
under the terms of this General Public License. The "Program", below,
|
| 65 |
+
refers to any such program or work, and a "work based on the Program"
|
| 66 |
+
means either the Program or any derivative work under copyright law:
|
| 67 |
+
that is to say, a work containing the Program or a portion of it,
|
| 68 |
+
either verbatim or with modifications and/or translated into another
|
| 69 |
+
language. (Hereinafter, translation is included without limitation in
|
| 70 |
+
the term "modification".) Each licensee is addressed as "you".
|
| 71 |
+
|
| 72 |
+
Activities other than copying, distribution and modification are not
|
| 73 |
+
covered by this License; they are outside its scope. The act of
|
| 74 |
+
running the Program is not restricted, and the output from the Program
|
| 75 |
+
is covered only if its contents constitute a work based on the
|
| 76 |
+
Program (independent of having been made by running the Program).
|
| 77 |
+
Whether that is true depends on what the Program does.
|
| 78 |
+
|
| 79 |
+
1. You may copy and distribute verbatim copies of the Program's
|
| 80 |
+
source code as you receive it, in any medium, provided that you
|
| 81 |
+
conspicuously and appropriately publish on each copy an appropriate
|
| 82 |
+
copyright notice and disclaimer of warranty; keep intact all the
|
| 83 |
+
notices that refer to this License and to the absence of any warranty;
|
| 84 |
+
and give any other recipients of the Program a copy of this License
|
| 85 |
+
along with the Program.
|
| 86 |
+
|
| 87 |
+
You may charge a fee for the physical act of transferring a copy, and
|
| 88 |
+
you may at your option offer warranty protection in exchange for a fee.
|
| 89 |
+
|
| 90 |
+
2. You may modify your copy or copies of the Program or any portion
|
| 91 |
+
of it, thus forming a work based on the Program, and copy and
|
| 92 |
+
distribute such modifications or work under the terms of Section 1
|
| 93 |
+
above, provided that you also meet all of these conditions:
|
| 94 |
+
|
| 95 |
+
a) You must cause the modified files to carry prominent notices
|
| 96 |
+
stating that you changed the files and the date of any change.
|
| 97 |
+
|
| 98 |
+
b) You must cause any work that you distribute or publish, that in
|
| 99 |
+
whole or in part contains or is derived from the Program or any
|
| 100 |
+
part thereof, to be licensed as a whole at no charge to all third
|
| 101 |
+
parties under the terms of this License.
|
| 102 |
+
|
| 103 |
+
c) If the modified program normally reads commands interactively
|
| 104 |
+
when run, you must cause it, when started running for such
|
| 105 |
+
interactive use in the most ordinary way, to print or display an
|
| 106 |
+
announcement including an appropriate copyright notice and a
|
| 107 |
+
notice that there is no warranty (or else, saying that you provide
|
| 108 |
+
a warranty) and that users may redistribute the program under
|
| 109 |
+
these conditions, and telling the user how to view a copy of this
|
| 110 |
+
License. (Exception: if the Program itself is interactive but
|
| 111 |
+
does not normally print such an announcement, your work based on
|
| 112 |
+
the Program is not required to print an announcement.)
|
| 113 |
+
|
| 114 |
+
These requirements apply to the modified work as a whole. If
|
| 115 |
+
identifiable sections of that work are not derived from the Program,
|
| 116 |
+
and can be reasonably considered independent and separate works in
|
| 117 |
+
themselves, then this License, and its terms, do not apply to those
|
| 118 |
+
sections when you distribute them as separate works. But when you
|
| 119 |
+
distribute the same sections as part of a whole which is a work based
|
| 120 |
+
on the Program, the distribution of the whole must be on the terms of
|
| 121 |
+
this License, whose permissions for other licensees extend to the
|
| 122 |
+
entire whole, and thus to each and every part regardless of who wrote it.
|
| 123 |
+
|
| 124 |
+
Thus, it is not the intent of this section to claim rights or contest
|
| 125 |
+
your rights to work written entirely by you; rather, the intent is to
|
| 126 |
+
exercise the right to control the distribution of derivative or
|
| 127 |
+
collective works based on the Program.
|
| 128 |
+
|
| 129 |
+
In addition, mere aggregation of another work not based on the Program
|
| 130 |
+
with the Program (or with a work based on the Program) on a volume of
|
| 131 |
+
a storage or distribution medium does not bring the other work under
|
| 132 |
+
the scope of this License.
|
| 133 |
+
|
| 134 |
+
3. You may copy and distribute the Program (or a work based on it,
|
| 135 |
+
under Section 2) in object code or executable form under the terms of
|
| 136 |
+
Sections 1 and 2 above provided that you also do one of the following:
|
| 137 |
+
|
| 138 |
+
a) Accompany it with the complete corresponding machine-readable
|
| 139 |
+
source code, which must be distributed under the terms of Sections
|
| 140 |
+
1 and 2 above on a medium customarily used for software interchange; or,
|
| 141 |
+
|
| 142 |
+
b) Accompany it with a written offer, valid for at least three
|
| 143 |
+
years, to give any third party, for a charge no more than your
|
| 144 |
+
cost of physically performing source distribution, a complete
|
| 145 |
+
machine-readable copy of the corresponding source code, to be
|
| 146 |
+
distributed under the terms of Sections 1 and 2 above on a medium
|
| 147 |
+
customarily used for software interchange; or,
|
| 148 |
+
|
| 149 |
+
c) Accompany it with the information you received as to the offer
|
| 150 |
+
to distribute corresponding source code. (This alternative is
|
| 151 |
+
allowed only for noncommercial distribution and only if you
|
| 152 |
+
received the program in object code or executable form with such
|
| 153 |
+
an offer, in accord with Subsection b above.)
|
| 154 |
+
|
| 155 |
+
The source code for a work means the preferred form of the work for
|
| 156 |
+
making modifications to it. For an executable work, complete source
|
| 157 |
+
code means all the source code for all modules it contains, plus any
|
| 158 |
+
associated interface definition files, plus the scripts used to
|
| 159 |
+
control compilation and installation of the executable. However, as a
|
| 160 |
+
special exception, the source code distributed need not include
|
| 161 |
+
anything that is normally distributed (in either source or binary
|
| 162 |
+
form) with the major components (compiler, kernel, and so on) of the
|
| 163 |
+
operating system on which the executable runs, unless that component
|
| 164 |
+
itself accompanies the executable.
|
| 165 |
+
|
| 166 |
+
If distribution of executable or object code is made by offering
|
| 167 |
+
access to copy from a designated place, then offering equivalent
|
| 168 |
+
access to copy the source code from the same place counts as
|
| 169 |
+
distribution of the source code, even though third parties are not
|
| 170 |
+
compelled to copy the source along with the object code.
|
| 171 |
+
|
| 172 |
+
4. You may not copy, modify, sublicense, or distribute the Program
|
| 173 |
+
except as expressly provided under this License. Any attempt
|
| 174 |
+
otherwise to copy, modify, sublicense or distribute the Program is
|
| 175 |
+
void, and will automatically terminate your rights under this License.
|
| 176 |
+
However, parties who have received copies, or rights, from you under
|
| 177 |
+
this License will not have their licenses terminated so long as such
|
| 178 |
+
parties remain in full compliance.
|
| 179 |
+
|
| 180 |
+
5. You are not required to accept this License, since you have not
|
| 181 |
+
signed it. However, nothing else grants you permission to modify or
|
| 182 |
+
distribute the Program or its derivative works. These actions are
|
| 183 |
+
prohibited by law if you do not accept this License. Therefore, by
|
| 184 |
+
modifying or distributing the Program (or any work based on the
|
| 185 |
+
Program), you indicate your acceptance of this License to do so, and
|
| 186 |
+
all its terms and conditions for copying, distributing or modifying
|
| 187 |
+
the Program or works based on it.
|
| 188 |
+
|
| 189 |
+
6. Each time you redistribute the Program (or any work based on the
|
| 190 |
+
Program), the recipient automatically receives a license from the
|
| 191 |
+
original licensor to copy, distribute or modify the Program subject to
|
| 192 |
+
these terms and conditions. You may not impose any further
|
| 193 |
+
restrictions on the recipients' exercise of the rights granted herein.
|
| 194 |
+
You are not responsible for enforcing compliance by third parties to
|
| 195 |
+
this License.
|
| 196 |
+
|
| 197 |
+
7. If, as a consequence of a court judgment or allegation of patent
|
| 198 |
+
infringement or for any other reason (not limited to patent issues),
|
| 199 |
+
conditions are imposed on you (whether by court order, agreement or
|
| 200 |
+
otherwise) that contradict the conditions of this License, they do not
|
| 201 |
+
excuse you from the conditions of this License. If you cannot
|
| 202 |
+
distribute so as to satisfy simultaneously your obligations under this
|
| 203 |
+
License and any other pertinent obligations, then as a consequence you
|
| 204 |
+
may not distribute the Program at all. For example, if a patent
|
| 205 |
+
license would not permit royalty-free redistribution of the Program by
|
| 206 |
+
all those who receive copies directly or indirectly through you, then
|
| 207 |
+
the only way you could satisfy both it and this License would be to
|
| 208 |
+
refrain entirely from distribution of the Program.
|
| 209 |
+
|
| 210 |
+
If any portion of this section is held invalid or unenforceable under
|
| 211 |
+
any particular circumstance, the balance of the section is intended to
|
| 212 |
+
apply and the section as a whole is intended to apply in other
|
| 213 |
+
circumstances.
|
| 214 |
+
|
| 215 |
+
It is not the purpose of this section to induce you to infringe any
|
| 216 |
+
patents or other property right claims or to contest validity of any
|
| 217 |
+
such claims; this section has the sole purpose of protecting the
|
| 218 |
+
integrity of the free software distribution system, which is
|
| 219 |
+
implemented by public license practices. Many people have made
|
| 220 |
+
generous contributions to the wide range of software distributed
|
| 221 |
+
through that system in reliance on consistent application of that
|
| 222 |
+
system; it is up to the author/donor to decide if he or she is willing
|
| 223 |
+
to distribute software through any other system and a licensee cannot
|
| 224 |
+
impose that choice.
|
| 225 |
+
|
| 226 |
+
This section is intended to make thoroughly clear what is believed to
|
| 227 |
+
be a consequence of the rest of this License.
|
| 228 |
+
|
| 229 |
+
8. If the distribution and/or use of the Program is restricted in
|
| 230 |
+
certain countries either by patents or by copyrighted interfaces, the
|
| 231 |
+
original copyright holder who places the Program under this License
|
| 232 |
+
may add an explicit geographical distribution limitation excluding
|
| 233 |
+
those countries, so that distribution is permitted only in or among
|
| 234 |
+
countries not thus excluded. In such case, this License incorporates
|
| 235 |
+
the limitation as if written in the body of this License.
|
| 236 |
+
|
| 237 |
+
9. The Free Software Foundation may publish revised and/or new versions
|
| 238 |
+
of the General Public License from time to time. Such new versions will
|
| 239 |
+
be similar in spirit to the present version, but may differ in detail to
|
| 240 |
+
address new problems or concerns.
|
| 241 |
+
|
| 242 |
+
Each version is given a distinguishing version number. If the Program
|
| 243 |
+
specifies a version number of this License which applies to it and "any
|
| 244 |
+
later version", you have the option of following the terms and conditions
|
| 245 |
+
either of that version or of any later version published by the Free
|
| 246 |
+
Software Foundation. If the Program does not specify a version number of
|
| 247 |
+
this License, you may choose any version ever published by the Free Software
|
| 248 |
+
Foundation.
|
| 249 |
+
|
| 250 |
+
10. If you wish to incorporate parts of the Program into other free
|
| 251 |
+
programs whose distribution conditions are different, write to the author
|
| 252 |
+
to ask for permission. For software which is copyrighted by the Free
|
| 253 |
+
Software Foundation, write to the Free Software Foundation; we sometimes
|
| 254 |
+
make exceptions for this. Our decision will be guided by the two goals
|
| 255 |
+
of preserving the free status of all derivatives of our free software and
|
| 256 |
+
of promoting the sharing and reuse of software generally.
|
| 257 |
+
|
| 258 |
+
NO WARRANTY
|
| 259 |
+
|
| 260 |
+
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
| 261 |
+
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
| 262 |
+
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
| 263 |
+
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
| 264 |
+
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
| 265 |
+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
| 266 |
+
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
| 267 |
+
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
| 268 |
+
REPAIR OR CORRECTION.
|
| 269 |
+
|
| 270 |
+
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
| 271 |
+
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
| 272 |
+
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
| 273 |
+
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
| 274 |
+
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
| 275 |
+
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
| 276 |
+
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
| 277 |
+
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
| 278 |
+
POSSIBILITY OF SUCH DAMAGES.
|
| 279 |
+
|
| 280 |
+
END OF TERMS AND CONDITIONS
|
| 281 |
+
|
| 282 |
+
How to Apply These Terms to Your New Programs
|
| 283 |
+
|
| 284 |
+
If you develop a new program, and you want it to be of the greatest
|
| 285 |
+
possible use to the public, the best way to achieve this is to make it
|
| 286 |
+
free software which everyone can redistribute and change under these terms.
|
| 287 |
+
|
| 288 |
+
To do so, attach the following notices to the program. It is safest
|
| 289 |
+
to attach them to the start of each source file to most effectively
|
| 290 |
+
convey the exclusion of warranty; and each file should have at least
|
| 291 |
+
the "copyright" line and a pointer to where the full notice is found.
|
| 292 |
+
|
| 293 |
+
<one line to give the program's name and a brief idea of what it does.>
|
| 294 |
+
Copyright (C) <year> <name of author>
|
| 295 |
+
|
| 296 |
+
This program is free software; you can redistribute it and/or modify
|
| 297 |
+
it under the terms of the GNU General Public License as published by
|
| 298 |
+
the Free Software Foundation; either version 2 of the License, or
|
| 299 |
+
(at your option) any later version.
|
| 300 |
+
|
| 301 |
+
This program is distributed in the hope that it will be useful,
|
| 302 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 303 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 304 |
+
GNU General Public License for more details.
|
| 305 |
+
|
| 306 |
+
You should have received a copy of the GNU General Public License along
|
| 307 |
+
with this program; if not, write to the Free Software Foundation, Inc.,
|
| 308 |
+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
| 309 |
+
|
| 310 |
+
Also add information on how to contact you by electronic and paper mail.
|
| 311 |
+
|
| 312 |
+
If the program is interactive, make it output a short notice like this
|
| 313 |
+
when it starts in an interactive mode:
|
| 314 |
+
|
| 315 |
+
Gnomovision version 69, Copyright (C) year name of author
|
| 316 |
+
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
| 317 |
+
This is free software, and you are welcome to redistribute it
|
| 318 |
+
under certain conditions; type `show c' for details.
|
| 319 |
+
|
| 320 |
+
The hypothetical commands `show w' and `show c' should show the appropriate
|
| 321 |
+
parts of the General Public License. Of course, the commands you use may
|
| 322 |
+
be called something other than `show w' and `show c'; they could even be
|
| 323 |
+
mouse-clicks or menu items--whatever suits your program.
|
| 324 |
+
|
| 325 |
+
You should also get your employer (if you work as a programmer) or your
|
| 326 |
+
school, if any, to sign a "copyright disclaimer" for the program, if
|
| 327 |
+
necessary. Here is a sample; alter the names:
|
| 328 |
+
|
| 329 |
+
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
| 330 |
+
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
| 331 |
+
|
| 332 |
+
<signature of Ty Coon>, 1 April 1989
|
| 333 |
+
Ty Coon, President of Vice
|
| 334 |
+
|
| 335 |
+
This General Public License does not permit incorporating your program into
|
| 336 |
+
proprietary programs. If your program is a subroutine library, you may
|
| 337 |
+
consider it more useful to permit linking proprietary applications with the
|
| 338 |
+
library. If this is what you want to do, use the GNU Lesser General
|
| 339 |
+
Public License instead of this License.
|
source/README.md
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
VimeML source/configuration from Git commit 9f0409ef7970c468efb622b207b1089de09651c1. GPL-2.0; see LICENSE.
|
| 2 |
+
The FP32 loader checks the original model and deployment code fingerprints.
|
| 3 |
+
Corpus texts, annotations, optimizer state and the separate Vime client are not included.
|
source/configs/corpus-parallel.toml
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Local parallel runner: one command starts all workers and merges automatically.
|
| 2 |
+
[inputs]
|
| 3 |
+
fineweb_paths = [
|
| 4 |
+
"datasets/fineweb-2-edu-japanese/train-00010-of-00283.parquet",
|
| 5 |
+
"datasets/fineweb-2-edu-japanese/train-00030-of-00283.parquet",
|
| 6 |
+
"datasets/fineweb-2-edu-japanese/train-00050-of-00283.parquet",
|
| 7 |
+
"datasets/fineweb-2-edu-japanese/train-00070-of-00283.parquet",
|
| 8 |
+
"datasets/fineweb-2-edu-japanese/train-00090-of-00283.parquet",
|
| 9 |
+
"datasets/fineweb-2-edu-japanese/train-00110-of-00283.parquet",
|
| 10 |
+
"datasets/fineweb-2-edu-japanese/train-00130-of-00283.parquet",
|
| 11 |
+
"datasets/fineweb-2-edu-japanese/train-00150-of-00283.parquet",
|
| 12 |
+
"datasets/fineweb-2-edu-japanese/train-00170-of-00283.parquet",
|
| 13 |
+
]
|
| 14 |
+
tatoeba_path = "datasets/Tatoeba/jpn_sentences.tsv"
|
| 15 |
+
calibration_ids = "annotations/calibration-documents-v1.json"
|
| 16 |
+
|
| 17 |
+
[build]
|
| 18 |
+
quality_mode = "rules_with_approved_annotations"
|
| 19 |
+
output_dir = "outputs/corpus-parallel-v1"
|
| 20 |
+
seed = 42
|
| 21 |
+
batch_size = 1024
|
| 22 |
+
max_join_chars = 2048
|
| 23 |
+
fineweb_documents_per_shard = 0
|
| 24 |
+
tatoeba_documents = 0
|
| 25 |
+
commit_every = 5000
|
| 26 |
+
progress_every = 5000
|
| 27 |
+
|
| 28 |
+
[review]
|
| 29 |
+
annotations = "annotations/approved-v1.jsonl"
|
| 30 |
+
require_all_annotations = true
|
| 31 |
+
|
| 32 |
+
[split]
|
| 33 |
+
train = 0.98
|
| 34 |
+
validation = 0.01
|
| 35 |
+
test = 0.01
|
source/configs/corpus-sharded.toml
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Same file on both machines; only --part and --output differ.
|
| 2 |
+
[inputs]
|
| 3 |
+
fineweb_paths = [
|
| 4 |
+
"datasets/fineweb-2-edu-japanese/train-00010-of-00283.parquet",
|
| 5 |
+
"datasets/fineweb-2-edu-japanese/train-00030-of-00283.parquet",
|
| 6 |
+
"datasets/fineweb-2-edu-japanese/train-00050-of-00283.parquet",
|
| 7 |
+
"datasets/fineweb-2-edu-japanese/train-00070-of-00283.parquet",
|
| 8 |
+
"datasets/fineweb-2-edu-japanese/train-00090-of-00283.parquet",
|
| 9 |
+
"datasets/fineweb-2-edu-japanese/train-00110-of-00283.parquet",
|
| 10 |
+
"datasets/fineweb-2-edu-japanese/train-00130-of-00283.parquet",
|
| 11 |
+
"datasets/fineweb-2-edu-japanese/train-00150-of-00283.parquet",
|
| 12 |
+
"datasets/fineweb-2-edu-japanese/train-00170-of-00283.parquet",
|
| 13 |
+
]
|
| 14 |
+
tatoeba_path = "datasets/Tatoeba/jpn_sentences.tsv"
|
| 15 |
+
calibration_ids = "annotations/calibration-documents-v1.json"
|
| 16 |
+
|
| 17 |
+
[build]
|
| 18 |
+
quality_mode = "rules_with_approved_annotations"
|
| 19 |
+
output_dir = "outputs/corpus-parts"
|
| 20 |
+
seed = 42
|
| 21 |
+
batch_size = 1024
|
| 22 |
+
max_join_chars = 2048
|
| 23 |
+
fineweb_documents_per_shard = 0
|
| 24 |
+
tatoeba_documents = 0
|
| 25 |
+
commit_every = 5000
|
| 26 |
+
progress_every = 5000
|
| 27 |
+
|
| 28 |
+
[review]
|
| 29 |
+
annotations = "annotations/approved-v1.jsonl"
|
| 30 |
+
require_all_annotations = true
|
| 31 |
+
|
| 32 |
+
[split]
|
| 33 |
+
train = 0.98
|
| 34 |
+
validation = 0.01
|
| 35 |
+
test = 0.01
|
source/configs/ime-eval-v1.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"version": "ime_diagnostic_v1",
|
| 3 |
+
"provenance": "Handwritten Japanese diagnostic cases, frozen before first evaluation. Synthetic homophone candidate lists, not AzooKey output. Training overlap unknown. References are non-exhaustive.",
|
| 4 |
+
"ranking": [
|
| 5 |
+
{"id":"hashi-food","group":"hashi","reading":"はし","context":"うどんを食べるために","candidates":["箸","橋","端"],"acceptable":["箸"]},
|
| 6 |
+
{"id":"hashi-river","group":"hashi","reading":"はし","context":"川を渡るための","candidates":["箸","橋","端"],"acceptable":["橋"]},
|
| 7 |
+
{"id":"hashi-edge","group":"hashi","reading":"はし","context":"机の中央ではなく","candidates":["箸","橋","端"],"acceptable":["端"]},
|
| 8 |
+
{"id":"au-friend","group":"au","reading":"あう","context":"駅で友人に","candidates":["会う","合う","遭う"],"acceptable":["会う"]},
|
| 9 |
+
{"id":"au-fit","group":"au","reading":"あう","context":"この服は体に","candidates":["会う","合う","遭う"],"acceptable":["合う"]},
|
| 10 |
+
{"id":"au-accident","group":"au","reading":"あう","context":"帰り道で事故に","candidates":["会う","合う","遭う"],"acceptable":["遭う"]},
|
| 11 |
+
{"id":"kikai-machine","group":"kikai","reading":"きかい","context":"工場で使う大きな","candidates":["機会","機械"],"acceptable":["機械"]},
|
| 12 |
+
{"id":"kikai-chance","group":"kikai","reading":"きかい","context":"もう一度挑戦する","candidates":["機会","機械"],"acceptable":["機会"]},
|
| 13 |
+
{"id":"kami-paper","group":"kami","reading":"かみ","context":"メモを書くための","candidates":["紙","髪","神"],"acceptable":["紙"]},
|
| 14 |
+
{"id":"kami-hair","group":"kami","reading":"かみ","context":"美容室で切ってもらった","candidates":["紙","髪","神"],"acceptable":["髪"]},
|
| 15 |
+
{"id":"kami-god","group":"kami","reading":"かみ","context":"神社に祀られている","candidates":["紙","髪","神"],"acceptable":["神"]},
|
| 16 |
+
{"id":"kouen-park","group":"kouen","reading":"こうえん","context":"子供たちが遊具で遊ぶ","candidates":["公園","講演","公演"],"acceptable":["公園"]},
|
| 17 |
+
{"id":"kouen-lecture","group":"kouen","reading":"こうえん","context":"大学の先生が研究成果について行う","candidates":["公園","講演","公演"],"acceptable":["講演"]},
|
| 18 |
+
{"id":"kouen-show","group":"kouen","reading":"こうえん","context":"劇場で行われるミュージカルの","candidates":["公園","講演","公演"],"acceptable":["公演"]},
|
| 19 |
+
{"id":"kanshou-art","group":"kanshou","reading":"かんしょう","context":"美術館で絵画を","candidates":["鑑賞","干渉"],"acceptable":["鑑賞"]},
|
| 20 |
+
{"id":"kanshou-interfere","group":"kanshou","reading":"かんしょう","context":"他人の私生活に過度に","candidates":["鑑賞","干渉"],"acceptable":["干渉"]},
|
| 21 |
+
{"id":"seikaku-personality","group":"seikaku","reading":"せいかく","context":"彼は明るく穏やかな","candidates":["性格","正確"],"acceptable":["性格"]},
|
| 22 |
+
{"id":"seikaku-accurate","group":"seikaku","reading":"せいかく","context":"この測定結果は非常に","candidates":["性格","正確"],"acceptable":["正確"]},
|
| 23 |
+
{"id":"hoshou-warranty","group":"hoshou","reading":"ほしょう","context":"製品が故障した場合の無料修理を","candidates":["保証","保障","補償"],"acceptable":["保証"]},
|
| 24 |
+
{"id":"hoshou-rights","group":"hoshou","reading":"ほしょう","context":"すべての国民の基本的人権を","candidates":["保証","保障","補償"],"acceptable":["保障"]},
|
| 25 |
+
{"id":"hoshou-damage","group":"hoshou","reading":"ほしょう","context":"事故による被害者の損害を","candidates":["保証","保障","補償"],"acceptable":["補償"]},
|
| 26 |
+
{"id":"ishi-stone","group":"ishi","reading":"いし","context":"川辺で拾った丸い","candidates":["石","意思","医師","意志"],"acceptable":["石"]},
|
| 27 |
+
{"id":"ishi-doctor","group":"ishi","reading":"いし","context":"病院で患者を診察する","candidates":["石","意思","医師","意志"],"acceptable":["医師"]},
|
| 28 |
+
{"id":"ishi-intent","group":"ishi","reading":"いし","context":"本人の同意や","candidates":["石","意思","医師","意志"],"acceptable":["意思","意志"],"note":"意思 is the preferred spelling here; 意志 is accepted conservatively as a meaningful variant."},
|
| 29 |
+
{"id":"atsui-weather","group":"atsui","reading":"あつい","context":"真夏の屋外はとても","candidates":["暑い","熱い","厚い"],"acceptable":["暑い"]},
|
| 30 |
+
{"id":"atsui-water","group":"atsui","reading":"あつい","context":"沸かしたばかりのお湯は","candidates":["暑い","熱い","厚い"],"acceptable":["熱い"]},
|
| 31 |
+
{"id":"atsui-book","group":"atsui","reading":"あつい","context":"この本はページが多くて","candidates":["暑い","熱い","厚い"],"acceptable":["厚い"]},
|
| 32 |
+
{"id":"naosu-repair","group":"naosu","reading":"なおす","context":"壊れたパソコンを","candidates":["直す","治す"],"acceptable":["直す"]},
|
| 33 |
+
{"id":"naosu-cure","group":"naosu","reading":"なおす","context":"薬を飲んで風邪を","candidates":["直す","治す"],"acceptable":["治す"]},
|
| 34 |
+
{"id":"kiku-medicine","group":"kiku","reading":"きく","context":"この薬は頭痛によく","candidates":["聞く","聴く","効く","利く"],"acceptable":["効く"]},
|
| 35 |
+
{"id":"kiku-listen","group":"kiku","reading":"きく","context":"会議で上司の説明を","candidates":["聞く","聴く","効く","利く"],"acceptable":["聞く","聴く"],"note":"Both listening spellings are accepted."},
|
| 36 |
+
{"id":"kiku-flexible","group":"kiku","reading":"きく","context":"小さな変更でも融通が","candidates":["聞く","聴く","効く","利く"],"acceptable":["利く"]}
|
| 37 |
+
],
|
| 38 |
+
"suggestions": [
|
| 39 |
+
{"id":"weather","prompt":"今日はとても","references":["いい天気","良い天気","暑い","寒い","楽しい","忙しい","暖かい","寒かった","暑かった","よかった","良かった"]},
|
| 40 |
+
{"id":"formal-thanks","prompt":"本日はお忙しい中","references":["ありがとうございます","ありがとうございました","お越しいただき","ご参加いただき","お集まりいただき","お時間をいただき"]},
|
| 41 |
+
{"id":"busy-request","prompt":"お忙しいところ","references":["ありがとうございます","ありがとうございました","恐れ入ります","申し訳ありません","恐縮ですが","お手数ですが","すみません"]},
|
| 42 |
+
{"id":"confirmation","prompt":"ご確認のほど","references":["よろしくお願いいたします","よろしくお願いします","お願いいたします","お願いします","お願い申し上げます"]},
|
| 43 |
+
{"id":"walk","prompt":"駅まで歩いて","references":["行きます","行く","向かいます","向かう","移動","約","五分","5分","10分"]},
|
| 44 |
+
{"id":"password","prompt":"パスワードを入力して","references":["ログイン","ください","下さい","次へ","認証","送信"]},
|
| 45 |
+
{"id":"form","prompt":"お名前とメールアドレスを","references":["入力してください","ご入力ください","記入してください","お知らせください","登録してください","入力","記入"]},
|
| 46 |
+
{"id":"cold","prompt":"風邪をひいたので","references":["休み","休む","病院","薬","寝","早く寝","会社を休","学校を休","今日は休","自宅で","家で","休養"]},
|
| 47 |
+
{"id":"attachment","prompt":"添付した資料の内容を","references":["ご確認ください","確認してください","ご確認いただけますか","確認","ご確認"]},
|
| 48 |
+
{"id":"reply","prompt":"お返事を","references":["お待ち","いただけ","ください","お願い","頂け"]},
|
| 49 |
+
{"id":"application","prompt":"このアプリは","references":["無料","簡単","スマートフォン","使い","便利","利用","対応"]},
|
| 50 |
+
{"id":"study","prompt":"日本語を勉強する","references":["ため","上で","とき","時","方法","こと"]},
|
| 51 |
+
{"id":"morning","prompt":"明日の朝は","references":["早く","早起き","雨","晴れ","学校","仕事","出発","午前"]},
|
| 52 |
+
{"id":"dinner","prompt":"夕食のあとに","references":["散歩","お風呂","デザート","お茶","家族","テレビ","寝","勉強"]}
|
| 53 |
+
]
|
| 54 |
+
}
|
source/configs/ime-homophones.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"version": "handchecked_homophones_v1",
|
| 3 |
+
"note": "Controlled same-reading candidate pools. Contexts and gold suitability still require blind verification. Alternative listening/intent spellings are excluded to reduce ambiguity.",
|
| 4 |
+
"groups": [
|
| 5 |
+
{"id":"hashi","reading":"はし","candidates":["箸","橋","端"]},
|
| 6 |
+
{"id":"au","reading":"あう","candidates":["会う","合う","遭う"]},
|
| 7 |
+
{"id":"kikai","reading":"きかい","candidates":["機会","機械"]},
|
| 8 |
+
{"id":"kami","reading":"かみ","candidates":["紙","髪","神"]},
|
| 9 |
+
{"id":"kouen","reading":"こうえん","candidates":["公園","講演","公演"]},
|
| 10 |
+
{"id":"kanshou","reading":"かんしょう","candidates":["鑑賞","干渉"]},
|
| 11 |
+
{"id":"seikaku","reading":"せいかく","candidates":["性格","正確"]},
|
| 12 |
+
{"id":"hoshou","reading":"ほしょう","candidates":["保証","保障","補償"]},
|
| 13 |
+
{"id":"ishi","reading":"いし","candidates":["石","医師"]},
|
| 14 |
+
{"id":"atsui","reading":"あつい","candidates":["暑い","熱い","厚い"]},
|
| 15 |
+
{"id":"naosu","reading":"なおす","candidates":["直す","治す"]},
|
| 16 |
+
{"id":"kiku","reading":"きく","candidates":["聞く","効く","利く"]}
|
| 17 |
+
]
|
| 18 |
+
}
|
source/configs/inference-prompts.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{"kind": "daily", "prompt": "今日はとても"},
|
| 3 |
+
{"kind": "daily", "prompt": "明日の朝は"},
|
| 4 |
+
{"kind": "daily", "prompt": "駅まで歩いて"},
|
| 5 |
+
{"kind": "daily", "prompt": "この本を読んで"},
|
| 6 |
+
{"kind": "learning", "prompt": "日本語を勉強する"},
|
| 7 |
+
{"kind": "business", "prompt": "お忙しいところ"},
|
| 8 |
+
{"kind": "business", "prompt": "本日はお忙しい中"},
|
| 9 |
+
{"kind": "technology", "prompt": "このアプリは"},
|
| 10 |
+
{"kind": "daily", "prompt": "最近、仕事が忙しくて"},
|
| 11 |
+
{"kind": "travel", "prompt": "東京駅から電車で"},
|
| 12 |
+
{"kind": "digits", "prompt": "2026年10月"},
|
| 13 |
+
{"kind": "latin", "prompt": "iPhoneで日本語を"}
|
| 14 |
+
]
|
source/configs/loader.toml
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Data validation only. No model is trained by this entry point.
|
| 2 |
+
token_dir = "artifacts/token-data/corpus-v1-16k"
|
| 3 |
+
index_dir = "artifacts/training-data/corpus-v1-c128"
|
| 4 |
+
context_length = 128
|
| 5 |
+
batch_size = 128
|
| 6 |
+
num_workers = 4
|
| 7 |
+
seed = 42
|
| 8 |
+
check_batches = 8
|
source/configs/phrase-demo-prompts.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{"id":"rain","scene":"天气","prompt":"今日は雨が降っているので、"},
|
| 3 |
+
{"id":"meeting","scene":"工作","prompt":"明日の会議までに、"},
|
| 4 |
+
{"id":"station","scene":"出行","prompt":"駅に着いたら、"},
|
| 5 |
+
{"id":"food","scene":"日常","prompt":"お腹が空いたので、"},
|
| 6 |
+
{"id":"thanks","scene":"商务","prompt":"本日はお忙しい中、"},
|
| 7 |
+
{"id":"confirmation","scene":"商务","prompt":"ご確認のほど、"},
|
| 8 |
+
{"id":"attachment","scene":"工作","prompt":"添付した資料を"},
|
| 9 |
+
{"id":"password","scene":"技术","prompt":"パスワードを入力して"},
|
| 10 |
+
{"id":"update","scene":"技术","prompt":"アプリを更新したら、"},
|
| 11 |
+
{"id":"travel","scene":"出行","prompt":"旅行に出かける前に、"},
|
| 12 |
+
{"id":"cold","scene":"日常","prompt":"風邪をひいたので、"},
|
| 13 |
+
{"id":"reading","scene":"日常","prompt":"寝る前に本を"},
|
| 14 |
+
{"id":"clothes","scene":"穿着","prompt":"外は寒いので、コートを"},
|
| 15 |
+
{"id":"movie","scene":"媒体","prompt":"昨日見た映画は"},
|
| 16 |
+
{"id":"practice","scene":"学习","prompt":"日本語が上手になるために、"},
|
| 17 |
+
{"id":"schedule","scene":"安排","prompt":"来週の月曜日は"},
|
| 18 |
+
{"id":"reply","scene":"工作","prompt":"お返事を"},
|
| 19 |
+
{"id":"dinner","scene":"日常","prompt":"夕食を食べた後、"},
|
| 20 |
+
{"id":"coffee","scene":"日常","prompt":"朝起きたら、コーヒーを"},
|
| 21 |
+
{"id":"friend","scene":"交流","prompt":"久しぶりに友達と"}
|
| 22 |
+
]
|
source/configs/tokenizer.toml
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Formal baseline: learn the vocabulary from a random sample of all train rows.
|
| 2 |
+
# LM training still uses the full corpus. Only a manual command starts training.
|
| 3 |
+
[paths]
|
| 4 |
+
corpus_dir = "outputs/corpus-fast-v1"
|
| 5 |
+
output_dir = "artifacts/tokenizers/ja-unigram-16k-v1"
|
| 6 |
+
|
| 7 |
+
[training]
|
| 8 |
+
model_type = "unigram"
|
| 9 |
+
vocab_size = 16384
|
| 10 |
+
character_coverage = 0.9995
|
| 11 |
+
byte_fallback = true
|
| 12 |
+
normalization_rule_name = "identity"
|
| 13 |
+
remove_extra_whitespaces = false
|
| 14 |
+
num_threads = 12
|
| 15 |
+
input_sentence_size = 2000000
|
| 16 |
+
seed = 42
|
| 17 |
+
max_sentence_length = 8192
|
| 18 |
+
|
| 19 |
+
[measurement]
|
| 20 |
+
# Independent processes; each native encoder uses one thread.
|
| 21 |
+
workers = 8
|
| 22 |
+
batch_size = 4096
|
| 23 |
+
|
| 24 |
+
[monitoring]
|
| 25 |
+
tensorboard = true
|
source/configs/train-smoke.toml
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# First manual run: pipeline correctness and measured throughput, not a final LM.
|
| 2 |
+
token_dir = "artifacts/token-data/corpus-v1-16k"
|
| 3 |
+
index_dir = "artifacts/training-data/corpus-v1-c128"
|
| 4 |
+
output_dir = "artifacts/models/tiny-ja-smoke-v1"
|
| 5 |
+
log_dir = "runs/training/tiny-ja-smoke-v1"
|
| 6 |
+
|
| 7 |
+
[model]
|
| 8 |
+
vocab_size = 16384
|
| 9 |
+
context_length = 128
|
| 10 |
+
d_model = 256
|
| 11 |
+
n_heads = 4
|
| 12 |
+
n_layers = 4
|
| 13 |
+
d_ff = 1024
|
| 14 |
+
dropout = 0.0
|
| 15 |
+
|
| 16 |
+
[training]
|
| 17 |
+
device = "cuda"
|
| 18 |
+
precision = "bf16"
|
| 19 |
+
seed = 42
|
| 20 |
+
cpu_threads = 4
|
| 21 |
+
batch_size = 128
|
| 22 |
+
num_workers = 4
|
| 23 |
+
bucket_multiplier = 64
|
| 24 |
+
gradient_accumulation = 1
|
| 25 |
+
max_steps = 300
|
| 26 |
+
learning_rate = 0.0003
|
| 27 |
+
min_learning_rate = 0.00003
|
| 28 |
+
warmup_steps = 30
|
| 29 |
+
weight_decay = 0.1
|
| 30 |
+
beta1 = 0.9
|
| 31 |
+
beta2 = 0.95
|
| 32 |
+
grad_clip = 1.0
|
| 33 |
+
log_every = 10
|
| 34 |
+
eval_every = 100
|
| 35 |
+
eval_batches = 16
|
| 36 |
+
checkpoint_every = 100
|
| 37 |
+
benchmark_warmup_steps = 20
|
source/configs/train-v1.toml
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# First formal baseline: exactly one full pass through the frozen corpus.
|
| 2 |
+
# 25,197,117 windows / batch128 = 196,853 updates, including the partial batch.
|
| 3 |
+
token_dir = "artifacts/token-data/corpus-v1-16k"
|
| 4 |
+
index_dir = "artifacts/training-data/corpus-v1-c128"
|
| 5 |
+
output_dir = "artifacts/models/tiny-ja-v1"
|
| 6 |
+
log_dir = "runs/training/tiny-ja-v1"
|
| 7 |
+
|
| 8 |
+
[model]
|
| 9 |
+
vocab_size = 16384
|
| 10 |
+
context_length = 128
|
| 11 |
+
d_model = 256
|
| 12 |
+
n_heads = 4
|
| 13 |
+
n_layers = 4
|
| 14 |
+
d_ff = 1024
|
| 15 |
+
dropout = 0.0
|
| 16 |
+
|
| 17 |
+
[training]
|
| 18 |
+
device = "cuda"
|
| 19 |
+
precision = "bf16"
|
| 20 |
+
seed = 42
|
| 21 |
+
cpu_threads = 4
|
| 22 |
+
batch_size = 128
|
| 23 |
+
num_workers = 4
|
| 24 |
+
bucket_multiplier = 64
|
| 25 |
+
gradient_accumulation = 1
|
| 26 |
+
epochs = 1
|
| 27 |
+
max_steps = 196853
|
| 28 |
+
learning_rate = 0.0003
|
| 29 |
+
min_learning_rate = 0.00003
|
| 30 |
+
warmup_steps = 2000
|
| 31 |
+
weight_decay = 0.1
|
| 32 |
+
beta1 = 0.9
|
| 33 |
+
beta2 = 0.95
|
| 34 |
+
grad_clip = 1.0
|
| 35 |
+
log_every = 100
|
| 36 |
+
eval_every = 5000
|
| 37 |
+
eval_batches = 128
|
| 38 |
+
checkpoint_every = 5000
|
| 39 |
+
benchmark_warmup_steps = 100
|
| 40 |
+
validate_full_at_end = true
|
source/requirements.txt
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Python >=3.11. Install from PyPI after selecting the appropriate PyTorch build.
|
| 2 |
+
# Windows/Linux CUDA 12.8: install torch==2.10.0 from the cu128 index first;
|
| 3 |
+
# then install this file using the default PyPI index. See docs/training.md.
|
| 4 |
+
numpy>=2,<3; sys_platform != "darwin"
|
| 5 |
+
# Core ML Tools 9.0's Torch scalar casts are incompatible with NumPy 2.4+.
|
| 6 |
+
numpy==2.3.5; sys_platform == "darwin"
|
| 7 |
+
pyarrow==25.0.1
|
| 8 |
+
sentencepiece==0.2.1
|
| 9 |
+
# Keep Windows training frozen; Core ML 9 lists PyTorch 2.7 support.
|
| 10 |
+
torch==2.10.0; sys_platform != "darwin"
|
| 11 |
+
torch==2.7.1; sys_platform == "darwin"
|
| 12 |
+
coremltools==9.0; sys_platform == "darwin"
|
| 13 |
+
# K-means palettes also process FP32 QKV weights in the conservative route.
|
| 14 |
+
scikit-learn==1.5.1; sys_platform == "darwin"
|
| 15 |
+
tensorboard==2.20.0
|
| 16 |
+
# TensorBoard 2.20 imports pkg_resources, removed in newer setuptools.
|
| 17 |
+
setuptools==80.9.0
|
| 18 |
+
wandb==0.30.0
|
| 19 |
+
# Manual model release authentication/upload/download; never runs during training.
|
| 20 |
+
huggingface_hub==2.1.1
|
source/scripts/benchmarks/evaluate.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Score a frozen, verified synthetic benchmark with a local checkpoint."""
|
| 2 |
+
import sys
|
| 3 |
+
from pathlib import Path
|
| 4 |
+
|
| 5 |
+
ROOT = Path(__file__).resolve().parents[2]
|
| 6 |
+
sys.path.insert(0, str(ROOT / "src"))
|
| 7 |
+
|
| 8 |
+
from vimeml.benchmarks.evaluate import main
|
| 9 |
+
|
| 10 |
+
if __name__ == "__main__":
|
| 11 |
+
main()
|
source/scripts/benchmarks/evaluate_ajimee.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Evaluate a frozen AJIMEE candidate export using the local Tiny Japanese LM."""
|
| 2 |
+
import sys
|
| 3 |
+
from pathlib import Path
|
| 4 |
+
|
| 5 |
+
ROOT = Path(__file__).resolve().parents[2]
|
| 6 |
+
sys.path.insert(0, str(ROOT / "src"))
|
| 7 |
+
|
| 8 |
+
from vimeml.benchmarks.evaluate_ajimee import main
|
| 9 |
+
|
| 10 |
+
if __name__ == "__main__":
|
| 11 |
+
main()
|
source/scripts/benchmarks/export_cached_development.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Export successful generation caches for review, even if other batches failed."""
|
| 2 |
+
import argparse
|
| 3 |
+
import json
|
| 4 |
+
import sys
|
| 5 |
+
from pathlib import Path
|
| 6 |
+
|
| 7 |
+
ROOT = Path(__file__).resolve().parents[2]
|
| 8 |
+
sys.path.insert(0, str(ROOT / "src"))
|
| 9 |
+
from vimeml.benchmarks.development import export_cached_drafts
|
| 10 |
+
from vimeml.review.multi_key import output_lock
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
def main():
|
| 14 |
+
parser = argparse.ArgumentParser(description=__doc__)
|
| 15 |
+
parser.add_argument("--source", type=Path, required=True)
|
| 16 |
+
parser.add_argument("--output", type=Path, required=True)
|
| 17 |
+
parser.add_argument("--exclude", type=Path, default=ROOT / "artifacts/benchmarks/ajimee-jwtd-v2-v1/evaluation_items.json")
|
| 18 |
+
args = parser.parse_args()
|
| 19 |
+
try:
|
| 20 |
+
with output_lock(args.output):
|
| 21 |
+
stats = export_cached_drafts(args.source, args.output, args.exclude)
|
| 22 |
+
print(json.dumps(stats, ensure_ascii=False, indent=2))
|
| 23 |
+
except (OSError, ValueError, KeyError) as error:
|
| 24 |
+
parser.exit(2, f"Error: {error}\n")
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
if __name__ == "__main__":
|
| 28 |
+
main()
|
source/scripts/benchmarks/generate.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Generate and blind-check a synthetic benchmark; no training."""
|
| 2 |
+
import sys
|
| 3 |
+
from pathlib import Path
|
| 4 |
+
|
| 5 |
+
ROOT = Path(__file__).resolve().parents[2]
|
| 6 |
+
sys.path.insert(0, str(ROOT / "src"))
|
| 7 |
+
|
| 8 |
+
from vimeml.benchmarks.generate import main
|
| 9 |
+
|
| 10 |
+
if __name__ == "__main__":
|
| 11 |
+
main()
|
source/scripts/benchmarks/generate_development.py
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Generate and independently verify kana-conversion development drafts."""
|
| 2 |
+
import sys
|
| 3 |
+
from pathlib import Path
|
| 4 |
+
|
| 5 |
+
ROOT = Path(__file__).resolve().parents[2]
|
| 6 |
+
sys.path.insert(0,str(ROOT / 'src'))
|
| 7 |
+
from vimeml.benchmarks.development import main
|
| 8 |
+
|
| 9 |
+
if __name__ == '__main__':
|
| 10 |
+
main()
|
source/scripts/benchmarks/hybrid.py
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Prepare development inputs, cache model scores and evaluate hybrid ranking."""
|
| 2 |
+
import sys
|
| 3 |
+
from pathlib import Path
|
| 4 |
+
|
| 5 |
+
ROOT = Path(__file__).resolve().parents[2]
|
| 6 |
+
sys.path.insert(0, str(ROOT / "src"))
|
| 7 |
+
from vimeml.benchmarks.hybrid import main
|
| 8 |
+
|
| 9 |
+
if __name__ == "__main__":
|
| 10 |
+
main()
|
source/scripts/benchmarks/prepare_ajimee.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Prepare downloaded AJIMEE data for the AzooKey CLI (stdlib only)."""
|
| 2 |
+
import sys
|
| 3 |
+
from pathlib import Path
|
| 4 |
+
|
| 5 |
+
ROOT = Path(__file__).resolve().parents[2]
|
| 6 |
+
sys.path.insert(0, str(ROOT / "src"))
|
| 7 |
+
|
| 8 |
+
from vimeml.benchmarks.ajimee import main
|
| 9 |
+
|
| 10 |
+
if __name__ == "__main__":
|
| 11 |
+
main()
|
source/scripts/corpus/build.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Command entry point; implementation lives in src/vimeml."""
|
| 2 |
+
|
| 3 |
+
import sys
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
|
| 6 |
+
ROOT = Path(__file__).resolve().parents[2]
|
| 7 |
+
sys.path.insert(0, str(ROOT / "src"))
|
| 8 |
+
|
| 9 |
+
from vimeml.corpus.build import main
|
| 10 |
+
|
| 11 |
+
if __name__ == "__main__":
|
| 12 |
+
main()
|
source/scripts/corpus/merge.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Merge completed cleaning parts using the verified parallel exporter."""
|
| 2 |
+
|
| 3 |
+
import argparse
|
| 4 |
+
import os
|
| 5 |
+
import sys
|
| 6 |
+
from pathlib import Path
|
| 7 |
+
|
| 8 |
+
ROOT = Path(__file__).resolve().parents[2]
|
| 9 |
+
sys.path.insert(0, str(ROOT / "src"))
|
| 10 |
+
from vimeml.data.merge_parts_fast import run
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
def main():
|
| 14 |
+
parser = argparse.ArgumentParser(description=__doc__)
|
| 15 |
+
parser.add_argument("--config", type=Path, default=ROOT / "configs/corpus-parallel.toml")
|
| 16 |
+
sources = parser.add_mutually_exclusive_group(required=True)
|
| 17 |
+
sources.add_argument("--parts", nargs="+", type=Path)
|
| 18 |
+
sources.add_argument("--parts-dir", type=Path)
|
| 19 |
+
parser.add_argument("--output", type=Path, required=True)
|
| 20 |
+
parser.add_argument("--work", type=Path)
|
| 21 |
+
parser.add_argument("--workers", type=int, default=min(8, os.cpu_count() or 1))
|
| 22 |
+
parser.add_argument("--buckets", type=int, default=64, choices=(1, 4, 16, 64, 256))
|
| 23 |
+
parser.add_argument("--cache-mb", type=int, default=128)
|
| 24 |
+
args = parser.parse_args()
|
| 25 |
+
parts = args.parts if args.parts is not None else sorted(p.parent for p in args.parts_dir.glob("*/manifest.json"))
|
| 26 |
+
if not parts:
|
| 27 |
+
parser.error("No completed parts found")
|
| 28 |
+
run(args.config, parts, args.output, workers=args.workers, buckets=args.buckets,
|
| 29 |
+
cache_mb=args.cache_mb, work=args.work)
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
if __name__ == "__main__":
|
| 33 |
+
main()
|
source/scripts/corpus/preprocess.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Command entry point; implementation lives in src/vimeml."""
|
| 2 |
+
|
| 3 |
+
import sys
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
|
| 6 |
+
ROOT = Path(__file__).resolve().parents[2]
|
| 7 |
+
sys.path.insert(0, str(ROOT / "src"))
|
| 8 |
+
|
| 9 |
+
from vimeml.data.preprocess_part import main
|
| 10 |
+
|
| 11 |
+
if __name__ == "__main__":
|
| 12 |
+
main()
|
source/scripts/deployment/ane_output_probe.py
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Manual reduced-output ANE experiment; not the deployment interface.
|
| 2 |
+
|
| 3 |
+
Usage: python scripts/deployment/ane_output_probe.py NEW_OUTPUT.mlpackage
|
| 4 |
+
Conversion, timing and accuracy checks start only when this command is run.
|
| 5 |
+
"""
|
| 6 |
+
import argparse
|
| 7 |
+
import sys
|
| 8 |
+
import time
|
| 9 |
+
from pathlib import Path
|
| 10 |
+
|
| 11 |
+
ROOT = Path(__file__).resolve().parents[2]
|
| 12 |
+
sys.path.insert(0, str(ROOT / "src"))
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def main():
|
| 16 |
+
parser = argparse.ArgumentParser(description=__doc__)
|
| 17 |
+
parser.add_argument("output", type=Path, help="New scratch .mlpackage path")
|
| 18 |
+
args = parser.parse_args()
|
| 19 |
+
out = args.output
|
| 20 |
+
if out.exists():
|
| 21 |
+
parser.error("Output exists; choose a new experiment path.")
|
| 22 |
+
if out.suffix != ".mlpackage":
|
| 23 |
+
parser.error("Output must end with .mlpackage.")
|
| 24 |
+
if sys.platform != "darwin":
|
| 25 |
+
parser.error("Run this experiment manually on Mac.")
|
| 26 |
+
import numpy as np, torch, coremltools as ct
|
| 27 |
+
from torch import nn
|
| 28 |
+
from vimeml.deployment.bundle import BundleLM
|
| 29 |
+
from vimeml.deployment.graph import ConversionGraph
|
| 30 |
+
lm = BundleLM(ROOT/"artifacts/deployment/tiny-ja-v1-inference-v1")
|
| 31 |
+
K = 16
|
| 32 |
+
class Head(nn.Module):
|
| 33 |
+
def __init__(s, model): super().__init__(); s.g = ConversionGraph(model)
|
| 34 |
+
def forward(s, input_ids, target_ids):
|
| 35 |
+
logp = torch.log_softmax(s.g(input_ids), dim=-1)
|
| 36 |
+
target = torch.gather(logp, 2, target_ids.long().unsqueeze(-1)).squeeze(-1)
|
| 37 |
+
top, idx = torch.topk(logp, K, dim=-1)
|
| 38 |
+
return target, top, idx.int()
|
| 39 |
+
h = Head(lm.model).eval()
|
| 40 |
+
ex = (torch.zeros(1,16,dtype=torch.int32), torch.zeros(1,16,dtype=torch.int32))
|
| 41 |
+
tr = torch.jit.trace(h, ex)
|
| 42 |
+
shapes = ct.EnumeratedShapes(shapes=[(1,L) for L in (16,32,64,128)], default=(1,16))
|
| 43 |
+
m = ct.convert(tr, convert_to="mlprogram", minimum_deployment_target=ct.target.iOS18, compute_precision=ct.precision.FLOAT16,
|
| 44 |
+
inputs=[ct.TensorType(name="input_ids", shape=shapes, dtype=np.int32), ct.TensorType(name="target_ids", shape=shapes, dtype=np.int32)],
|
| 45 |
+
outputs=[ct.TensorType(name="target_logprobs", dtype=np.float32), ct.TensorType(name="top_logprobs", dtype=np.float32), ct.TensorType(name="top_ids", dtype=np.int32)])
|
| 46 |
+
m.save(str(out))
|
| 47 |
+
for units in ("CPU_ONLY","CPU_AND_NE"):
|
| 48 |
+
mm = ct.models.MLModel(str(out), compute_units=getattr(ct.ComputeUnit, units)); row=[units]
|
| 49 |
+
for L in (16,64,128):
|
| 50 |
+
x={"input_ids":np.full((1,L),5,np.int32),"target_ids":np.full((1,L),6,np.int32)}; mm.predict(x); ts=[]
|
| 51 |
+
for _ in range(20): t=time.perf_counter(); mm.predict(x); ts.append((time.perf_counter()-t)*1000)
|
| 52 |
+
row.append(f"T{L}={np.median(ts):.2f}ms")
|
| 53 |
+
print(" ".join(row))
|
| 54 |
+
# accuracy vs FP32 on AJIMEE text
|
| 55 |
+
import json
|
| 56 |
+
items=json.load(open(ROOT/"artifacts/benchmarks/ajimee-jwtd-v2-v1/evaluation_items.json"))
|
| 57 |
+
mm = ct.models.MLModel(str(out), compute_units=ct.ComputeUnit.CPU_AND_NE)
|
| 58 |
+
diffs=[]; topagree=[]
|
| 59 |
+
for it in items[:100]:
|
| 60 |
+
ids=[2]+lm.processor.encode((it.get("context_text") or "")+it["expected_output"][0])[:127]
|
| 61 |
+
n=len(ids)-1; L=next(b for b in (16,32,64,128) if b>=n)
|
| 62 |
+
inp=np.zeros((1,L),np.int32); inp[0,:n]=ids[:-1]; tgt=np.zeros((1,L),np.int32); tgt[0,:n]=ids[1:]
|
| 63 |
+
o=mm.predict({"input_ids":inp,"target_ids":tgt})
|
| 64 |
+
with torch.no_grad(): ref=lm.model(torch.tensor([ids[:-1]])).float().log_softmax(-1)[0]
|
| 65 |
+
r=ref.gather(1,torch.tensor(ids[1:])[:,None]).squeeze(1).numpy()
|
| 66 |
+
diffs.append(abs(o["target_logprobs"][0,:n]-r).max())
|
| 67 |
+
topagree.append(np.mean(o["top_ids"][0,:n,0]==ref.argmax(-1).numpy()))
|
| 68 |
+
print(f"ANE target logprob max|diff| mean={np.mean(diffs):.4f} max={np.max(diffs):.4f}; top1 agree={np.mean(topagree):.4f}")
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
if __name__ == "__main__":
|
| 72 |
+
main()
|
source/scripts/deployment/compare_quantization.py
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Distribution-level check of a Core ML package against the FP32 bundle.
|
| 2 |
+
|
| 3 |
+
Distribution diagnostics supplement the strict logits, PAD and ranking checks.
|
| 4 |
+
They do not establish exact conversion equivalence. This reports KL(FP32 || model),
|
| 5 |
+
NLL on real text, top-1 agreement and, as a control, the same metrics for a
|
| 6 |
+
PyTorch simulation of symmetric INT8 block quantization. Read-only.
|
| 7 |
+
"""
|
| 8 |
+
import argparse
|
| 9 |
+
import copy
|
| 10 |
+
import json
|
| 11 |
+
import sys
|
| 12 |
+
from pathlib import Path
|
| 13 |
+
|
| 14 |
+
ROOT = Path(__file__).resolve().parents[2]
|
| 15 |
+
sys.path.insert(0, str(ROOT / "src"))
|
| 16 |
+
|
| 17 |
+
import numpy as np
|
| 18 |
+
import torch
|
| 19 |
+
|
| 20 |
+
from vimeml.deployment.bundle import BundleLM, environment
|
| 21 |
+
from vimeml.deployment.coreml import verify_package
|
| 22 |
+
from vimeml.training.data import file_sha
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def simulate_int8(model, block):
|
| 26 |
+
"""Mirror the conservative recipe: FP16 storage except QKV/positions, then INT8 per block."""
|
| 27 |
+
if block <= 0 or any(p.ndim == 2 and p.shape[1] % block for p in model.parameters()):
|
| 28 |
+
raise ValueError("Block size must be positive and divide every matrix input dimension.")
|
| 29 |
+
result = copy.deepcopy(model)
|
| 30 |
+
with torch.no_grad():
|
| 31 |
+
for name, parameter in result.named_parameters():
|
| 32 |
+
if parameter.ndim != 2:
|
| 33 |
+
continue
|
| 34 |
+
weight = parameter if ("qkv" in name or "position" in name) else parameter.half().float()
|
| 35 |
+
rows, columns = weight.shape
|
| 36 |
+
blocks = weight.reshape(rows, columns // block, block)
|
| 37 |
+
scale = blocks.abs().amax(-1, keepdim=True).clamp_min(1e-12) / 127
|
| 38 |
+
parameter.copy_((torch.round(blocks / scale).clamp(-127, 127) * scale).reshape(rows, columns))
|
| 39 |
+
return result
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
def texts(benchmark):
|
| 43 |
+
items = json.loads((benchmark / "evaluation_items.json").read_text(encoding="utf-8"))
|
| 44 |
+
return [(item.get("context_text") or "") + item["expected_output"][0] for item in items]
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
def compare(lm, model, mlmodel, sequences):
|
| 48 |
+
metrics = {key: [] for key in ("kl_coreml", "kl_simulated", "nll_fp32", "nll_coreml",
|
| 49 |
+
"top1_agreement", "max_logprob_diff")}
|
| 50 |
+
for ids in sequences:
|
| 51 |
+
tensor = torch.tensor([ids])
|
| 52 |
+
with torch.no_grad():
|
| 53 |
+
reference = lm.model(tensor)[0].float().log_softmax(-1)
|
| 54 |
+
simulated = model(tensor)[0].float().log_softmax(-1)
|
| 55 |
+
logits = mlmodel.predict({"input_ids": np.array([ids], dtype=np.int32)})["logits"][0]
|
| 56 |
+
coreml = torch.tensor(logits).log_softmax(-1)
|
| 57 |
+
probabilities = reference.exp()
|
| 58 |
+
metrics["kl_coreml"].append((probabilities * (reference - coreml)).sum(-1).mean().item())
|
| 59 |
+
metrics["kl_simulated"].append((probabilities * (reference - simulated)).sum(-1).mean().item())
|
| 60 |
+
targets = tensor[0, 1:, None]
|
| 61 |
+
metrics["nll_fp32"].append(-reference[:-1].gather(-1, targets).mean().item())
|
| 62 |
+
metrics["nll_coreml"].append(-coreml[:-1].gather(-1, targets).mean().item())
|
| 63 |
+
metrics["top1_agreement"].append((reference.argmax(-1) == coreml.argmax(-1)).float().mean().item())
|
| 64 |
+
metrics["max_logprob_diff"].append((reference - coreml).abs().max().item())
|
| 65 |
+
return {key: {"mean": float(np.mean(values)), "max": float(np.max(values))} for key, values in metrics.items()}
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
def main():
|
| 69 |
+
parser = argparse.ArgumentParser(description=__doc__)
|
| 70 |
+
parser.add_argument("--bundle", type=Path, default=ROOT / "artifacts/deployment/tiny-ja-v1-inference-v1")
|
| 71 |
+
parser.add_argument("--model", type=Path, required=True, help="Core ML experiment directory with model.mlpackage")
|
| 72 |
+
parser.add_argument("--benchmark", type=Path, default=ROOT / "artifacts/benchmarks/ajimee-jwtd-v2-v1")
|
| 73 |
+
parser.add_argument("--block-size", type=int, default=32)
|
| 74 |
+
parser.add_argument("--compute-units", choices=("CPU_ONLY", "CPU_AND_GPU", "CPU_AND_NE", "ALL"), default="CPU_ONLY")
|
| 75 |
+
parser.add_argument("--output", type=Path, help="Optional JSON report path; must not exist.")
|
| 76 |
+
args = parser.parse_args()
|
| 77 |
+
if args.output and args.output.exists():
|
| 78 |
+
parser.error("Output exists.")
|
| 79 |
+
lm = BundleLM(args.bundle)
|
| 80 |
+
manifest = verify_package(args.model)
|
| 81 |
+
if manifest["bundle"]["bundle_manifest_sha256"] != lm.metadata["bundle_manifest_sha256"]:
|
| 82 |
+
raise ValueError("Core ML model and FP32 bundle identities differ.")
|
| 83 |
+
if sys.platform != "darwin":
|
| 84 |
+
parser.error("Run Core ML prediction manually on Mac.")
|
| 85 |
+
import coremltools as ct
|
| 86 |
+
torch.set_num_threads(4)
|
| 87 |
+
mlmodel = ct.models.MLModel(str(args.model / "model.mlpackage"),
|
| 88 |
+
compute_units=getattr(ct.ComputeUnit, args.compute_units))
|
| 89 |
+
simulated = simulate_int8(lm.model, args.block_size).eval()
|
| 90 |
+
limit = lm.model.config.context_length - 1
|
| 91 |
+
encoded = [lm.processor.encode(text) for text in texts(args.benchmark)]
|
| 92 |
+
if not encoded or any(not ids for ids in encoded):
|
| 93 |
+
raise ValueError("Benchmark must have at least one nonempty target token per example.")
|
| 94 |
+
real = [[lm.special["bos"], *ids[:limit]] for ids in encoded]
|
| 95 |
+
rng = np.random.default_rng(0)
|
| 96 |
+
random = [[lm.special["bos"], *rng.integers(4, lm.model.config.vocab_size, limit).tolist()] for _ in range(5)]
|
| 97 |
+
report = {"format": "vimeml_distribution_diagnostic_v2", "model": str(args.model),
|
| 98 |
+
"compute_units": args.compute_units, "environment": environment(),
|
| 99 |
+
"bundle_manifest_sha256": lm.metadata["bundle_manifest_sha256"],
|
| 100 |
+
"coreml_manifest_sha256": file_sha(args.model / "manifest.json"),
|
| 101 |
+
"benchmark_items_sha256": file_sha(args.benchmark / "evaluation_items.json"),
|
| 102 |
+
"simulation": {"block_size": args.block_size,
|
| 103 |
+
"note": "FP32 scales and symmetric +/-127 rounding; not exact Core ML scale storage or kernels."},
|
| 104 |
+
"sampling": {"examples": len(encoded), "content_token_limit": limit,
|
| 105 |
+
"truncated_examples": sum(len(ids) > limit for ids in encoded),
|
| 106 |
+
"aggregation": "Mean of each example's position mean; not token-weighted corpus mean.",
|
| 107 |
+
"kl_top1_include_last_position": True, "nll_excludes_last_position": True,
|
| 108 |
+
"random_sequences": 5, "random_seed": 0},
|
| 109 |
+
"benchmark_text": compare(lm, simulated, mlmodel, real),
|
| 110 |
+
"random_tokens": compare(lm, simulated, mlmodel, random)}
|
| 111 |
+
text = json.dumps(report, ensure_ascii=False, indent=2)
|
| 112 |
+
print(text)
|
| 113 |
+
if args.output:
|
| 114 |
+
args.output.parent.mkdir(parents=True, exist_ok=True)
|
| 115 |
+
args.output.write_text(text + "\n", encoding="utf-8")
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
if __name__ == "__main__":
|
| 119 |
+
main()
|
source/scripts/deployment/compute_plan.py
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Report where Core ML would place each op of a package (CPU / GPU / Neural Engine).
|
| 2 |
+
|
| 3 |
+
Uses MLComputePlan on this Mac. Placement on iPhone can differ; confirm with a device run.
|
| 4 |
+
"""
|
| 5 |
+
import argparse
|
| 6 |
+
import json
|
| 7 |
+
import shutil
|
| 8 |
+
import tempfile
|
| 9 |
+
from collections import Counter
|
| 10 |
+
from pathlib import Path
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
def plan(package, units):
|
| 14 |
+
import coremltools as ct
|
| 15 |
+
from coremltools.models.compute_plan import MLComputePlan
|
| 16 |
+
from coremltools.models.compute_device import MLCPUComputeDevice, MLGPUComputeDevice, MLNeuralEngineComputeDevice
|
| 17 |
+
|
| 18 |
+
names = {MLCPUComputeDevice: "cpu", MLGPUComputeDevice: "gpu", MLNeuralEngineComputeDevice: "ane"}
|
| 19 |
+
temporary = Path(tempfile.mkdtemp())
|
| 20 |
+
try:
|
| 21 |
+
compiled = ct.utils.compile_model(str(package), str(temporary / "model.mlmodelc"))
|
| 22 |
+
compute_plan = MLComputePlan.load_from_path(path=str(compiled), compute_units=getattr(ct.ComputeUnit, units))
|
| 23 |
+
program = compute_plan.model_structure.program
|
| 24 |
+
placement, cost, details = Counter(), Counter(), []
|
| 25 |
+
for function in program.functions.values():
|
| 26 |
+
for operation in function.block.operations:
|
| 27 |
+
usage = compute_plan.get_compute_device_usage_for_mlprogram_operation(operation)
|
| 28 |
+
if usage is None:
|
| 29 |
+
continue
|
| 30 |
+
device = names.get(type(usage.preferred_compute_device), "other")
|
| 31 |
+
estimate = compute_plan.get_estimated_cost_for_mlprogram_operation(operation)
|
| 32 |
+
weight = estimate.weight if estimate else 0.0
|
| 33 |
+
placement[device] += 1
|
| 34 |
+
cost[device] += weight
|
| 35 |
+
details.append({"op": operation.operator_name, "device": device, "cost": weight,
|
| 36 |
+
"supported": sorted({names.get(type(d), "other")
|
| 37 |
+
for d in usage.supported_compute_devices})})
|
| 38 |
+
return {"package": str(package), "compute_units": units, "ops_by_device": dict(placement),
|
| 39 |
+
"estimated_cost_by_device": {k: round(v, 4) for k, v in cost.items()}, "ops": details}
|
| 40 |
+
finally:
|
| 41 |
+
shutil.rmtree(temporary, ignore_errors=True)
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def main():
|
| 45 |
+
parser = argparse.ArgumentParser(description=__doc__)
|
| 46 |
+
parser.add_argument("--model", type=Path, required=True, help="Experiment directory with model.mlpackage")
|
| 47 |
+
parser.add_argument("--compute-units", default="CPU_AND_NE", choices=("CPU_ONLY", "CPU_AND_GPU", "CPU_AND_NE", "ALL"))
|
| 48 |
+
parser.add_argument("--details", action="store_true", help="Print every op")
|
| 49 |
+
args = parser.parse_args()
|
| 50 |
+
report = plan(args.model / "model.mlpackage", args.compute_units)
|
| 51 |
+
if not args.details:
|
| 52 |
+
report.pop("ops")
|
| 53 |
+
print(json.dumps(report, indent=2))
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
if __name__ == "__main__":
|
| 57 |
+
main()
|
source/scripts/deployment/coreml.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Manual deployment CLI: no training, API calls or automatic stage chaining."""
|
| 2 |
+
import sys
|
| 3 |
+
from pathlib import Path
|
| 4 |
+
|
| 5 |
+
ROOT = Path(__file__).resolve().parents[2]
|
| 6 |
+
sys.path.insert(0, str(ROOT / "src"))
|
| 7 |
+
|
| 8 |
+
from vimeml.deployment.cli import main
|
| 9 |
+
|
| 10 |
+
if __name__ == "__main__":
|
| 11 |
+
main()
|
source/scripts/deployment/coreml_ane.py
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Neural Engine variant: FP16 computation, enumerated input lengths, optional INT8 weights.
|
| 2 |
+
|
| 3 |
+
The conservative package computes in FP32, which the Neural Engine cannot execute, so every
|
| 4 |
+
op falls back to CPU. This entry converts the same traced graph with FP16 computation and a
|
| 5 |
+
small set of fixed lengths (callers right-pad to the next length; PAD never affects valid
|
| 6 |
+
positions under the causal mask), then optionally applies per-channel INT8 weight quantization.
|
| 7 |
+
"""
|
| 8 |
+
import argparse
|
| 9 |
+
import sys
|
| 10 |
+
from pathlib import Path
|
| 11 |
+
|
| 12 |
+
ROOT = Path(__file__).resolve().parents[2]
|
| 13 |
+
sys.path.insert(0, str(ROOT / "src"))
|
| 14 |
+
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
| 15 |
+
|
| 16 |
+
import numpy as np
|
| 17 |
+
import torch
|
| 18 |
+
|
| 19 |
+
from vimeml.deployment.bundle import BundleLM
|
| 20 |
+
from vimeml.deployment.coreml import coremltools, finish, inspect_spec, verify_package
|
| 21 |
+
from vimeml.deployment.graph import trace_graph
|
| 22 |
+
from vimeml.training.data import file_sha
|
| 23 |
+
from coreml_conservative import parameter_compression_config
|
| 24 |
+
|
| 25 |
+
LENGTHS = (16, 32, 64, 128)
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
def convert(bundle, output, lengths):
|
| 29 |
+
ct = coremltools()
|
| 30 |
+
lm = BundleLM(bundle)
|
| 31 |
+
shapes = ct.EnumeratedShapes(shapes=[(1, length) for length in lengths], default=(1, lengths[0]))
|
| 32 |
+
model = ct.convert(trace_graph(lm.model), source="pytorch", convert_to="mlprogram",
|
| 33 |
+
minimum_deployment_target=ct.target.iOS18, compute_precision=ct.precision.FLOAT16,
|
| 34 |
+
inputs=[ct.TensorType(name="input_ids", shape=shapes, dtype=np.int32)],
|
| 35 |
+
outputs=[ct.TensorType(name="logits", dtype=np.float32)], skip_model_load=True)
|
| 36 |
+
model.short_description = "Frozen TinyGPT; FP16 computation for the Neural Engine; enumerated lengths; no KV cache."
|
| 37 |
+
model.user_defined_metadata["bundle_manifest_sha256"] = lm.metadata["bundle_manifest_sha256"]
|
| 38 |
+
finish(output, model, {"kind": "fp16_ane", "minimum_ios": 18, "bundle": lm.metadata, "lengths": list(lengths),
|
| 39 |
+
"conversion_script_sha256": file_sha(Path(__file__)),
|
| 40 |
+
"interface": {"input_ids": f"int32 [1,T], T in {list(lengths)}; right-pad with PAD=0",
|
| 41 |
+
"logits": "float32 [1,T,16384]; FP16 computation; no softmax"}})
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def compress(source, output):
|
| 45 |
+
ct = coremltools()
|
| 46 |
+
original = verify_package(source)
|
| 47 |
+
if original["kind"] != "fp16_ane":
|
| 48 |
+
raise ValueError("Compress an uncompressed fp16_ane conversion.")
|
| 49 |
+
from coremltools.optimize import coreml as opt
|
| 50 |
+
model = ct.models.MLModel(str(source / "model.mlpackage"), skip_model_load=True)
|
| 51 |
+
config = opt.OpLinearQuantizerConfig(mode="linear_symmetric", dtype="int8",
|
| 52 |
+
granularity="per_channel", weight_threshold=2048)
|
| 53 |
+
optimization_config, selection = parameter_compression_config(opt, model, config)
|
| 54 |
+
result = opt.linear_quantize_weights(model, config=optimization_config)
|
| 55 |
+
if not any(name.startswith("constexpr_") for name in inspect_spec(result)["operations"]):
|
| 56 |
+
raise ValueError("No compressed constexpr weights found.")
|
| 57 |
+
finish(output, result, {"kind": "linear8_fp16_ane", "minimum_ios": 18, "bundle": original["bundle"],
|
| 58 |
+
"lengths": original["lengths"], "interface": original["interface"],
|
| 59 |
+
"source_manifest_sha256": file_sha(source / "manifest.json"),
|
| 60 |
+
"conversion_script_sha256": file_sha(Path(__file__)),
|
| 61 |
+
"compression": {"method": "linear", "bits": 8, "granularity": "per_channel", "weight_threshold": 2048,
|
| 62 |
+
"selection": selection,
|
| 63 |
+
"scope": "Learned matrices only; masks and small constants unchanged; FP16 activations."}})
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
def main():
|
| 67 |
+
parser = argparse.ArgumentParser(description=__doc__)
|
| 68 |
+
sub = parser.add_subparsers(dest="command", required=True)
|
| 69 |
+
convert_parser = sub.add_parser("convert")
|
| 70 |
+
convert_parser.add_argument("--bundle", type=Path, required=True)
|
| 71 |
+
convert_parser.add_argument("--lengths", type=int, nargs="+", default=list(LENGTHS))
|
| 72 |
+
compress_parser = sub.add_parser("compress")
|
| 73 |
+
compress_parser.add_argument("--source", type=Path, required=True)
|
| 74 |
+
for command in (convert_parser, compress_parser):
|
| 75 |
+
command.add_argument("--output", type=Path, required=True)
|
| 76 |
+
args = parser.parse_args()
|
| 77 |
+
if args.output.exists():
|
| 78 |
+
parser.error("Output exists; use a new versioned directory.")
|
| 79 |
+
torch.set_num_threads(4)
|
| 80 |
+
if args.command == "convert":
|
| 81 |
+
lengths = sorted(set(args.lengths))
|
| 82 |
+
if lengths[0] < 1 or lengths[-1] != 128:
|
| 83 |
+
parser.error("Lengths must be positive and include 128.")
|
| 84 |
+
convert(args.bundle, args.output, lengths)
|
| 85 |
+
else:
|
| 86 |
+
compress(args.source, args.output)
|
| 87 |
+
print(f"Output: {args.output.resolve()}")
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
if __name__ == "__main__":
|
| 91 |
+
main()
|
source/scripts/deployment/coreml_conservative.py
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""FP16 weight-storage baseline and weight-only quantization with FP32 computation.
|
| 2 |
+
|
| 3 |
+
Kept outside the frozen deployment sources so an existing inference bundle
|
| 4 |
+
remains verifiable. This converter's hash and exact precision policy are saved
|
| 5 |
+
in the package manifest. Stages preserve prior experiment directories.
|
| 6 |
+
"""
|
| 7 |
+
import argparse
|
| 8 |
+
import sys
|
| 9 |
+
from pathlib import Path
|
| 10 |
+
|
| 11 |
+
ROOT = Path(__file__).resolve().parents[2]
|
| 12 |
+
sys.path.insert(0, str(ROOT / "src"))
|
| 13 |
+
|
| 14 |
+
import numpy as np
|
| 15 |
+
import torch
|
| 16 |
+
|
| 17 |
+
from vimeml.deployment.bundle import BundleLM, read_json
|
| 18 |
+
from vimeml.deployment.coreml import coremltools, finish, inspect_spec, verify_package
|
| 19 |
+
from vimeml.deployment.graph import trace_graph
|
| 20 |
+
from vimeml.training.data import file_sha
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def weight_storage_graph(ct, traced, context_length, target=18):
|
| 24 |
+
from coremltools.converters.mil import Builder as mb
|
| 25 |
+
from coremltools.converters.mil.mil.scope import ScopeInfo
|
| 26 |
+
|
| 27 |
+
program = ct.convert(traced, source="pytorch", convert_to="milinternal",
|
| 28 |
+
minimum_deployment_target=getattr(ct.target, f"iOS{target}"), compute_precision=ct.precision.FLOAT32,
|
| 29 |
+
inputs=[ct.TensorType(name="input_ids", shape=(1, ct.RangeDim(lower_bound=1,
|
| 30 |
+
upper_bound=context_length, default=min(16, context_length))), dtype=np.int32)],
|
| 31 |
+
outputs=[ct.TensorType(name="logits", dtype=np.float32)])
|
| 32 |
+
changed = {"fp16_linear_layers": 0, "fp16_token_embedding_tables": 0,
|
| 33 |
+
"fp32_qkv_layers": 0, "fp32_position_embedding_tables": 0}
|
| 34 |
+
for function in program.functions.values():
|
| 35 |
+
with function:
|
| 36 |
+
for op in list(function.operations):
|
| 37 |
+
if op.op_type == "linear":
|
| 38 |
+
if "attention.qkv" in op.weight.name:
|
| 39 |
+
changed["fp32_qkv_layers"] += 1
|
| 40 |
+
continue
|
| 41 |
+
with mb.scope(*[ScopeInfo(source=source, data=data)
|
| 42 |
+
for source, data in op.scopes.items()]), mb.set_before_op(op):
|
| 43 |
+
weight = mb.const(val=op.weight.val.astype(np.float16),
|
| 44 |
+
name=op.weight.name + "_storage_fp16")
|
| 45 |
+
arguments = {"weight": weight}
|
| 46 |
+
if op.bias is not None:
|
| 47 |
+
arguments["bias"] = mb.const(val=op.bias.val.astype(np.float16),
|
| 48 |
+
name=op.bias.name + "_storage_fp16")
|
| 49 |
+
result = mb.linear(x=op.x, name=op.name + "_compute_fp32", **arguments)
|
| 50 |
+
function.replace_uses_of_var_after_op(anchor_op=op,
|
| 51 |
+
old_var=op.outputs[0], new_var=result)
|
| 52 |
+
function.remove_ops([op])
|
| 53 |
+
changed["fp16_linear_layers"] += 1
|
| 54 |
+
elif (op.op_type == "gather" and op.x.val is not None and
|
| 55 |
+
op.x.val.dtype == np.float32):
|
| 56 |
+
if "position_embedding" in op.x.name:
|
| 57 |
+
changed["fp32_position_embedding_tables"] += 1
|
| 58 |
+
continue
|
| 59 |
+
if "token_embedding" not in op.x.name:
|
| 60 |
+
raise ValueError("Unexpected floating-point gather table; inspect the graph.")
|
| 61 |
+
with mb.scope(*[ScopeInfo(source=source, data=data)
|
| 62 |
+
for source, data in op.scopes.items()]), mb.set_before_op(op):
|
| 63 |
+
table = mb.const(val=op.x.val.astype(np.float16),
|
| 64 |
+
name=op.x.name + "_storage_fp16")
|
| 65 |
+
gathered = mb.gather(x=table, indices=op.indices, axis=op.axis,
|
| 66 |
+
name=op.name + "_storage_fp16")
|
| 67 |
+
result = mb.cast(x=gathered, dtype="fp32", name=op.name + "_compute_fp32")
|
| 68 |
+
function.replace_uses_of_var_after_op(anchor_op=op,
|
| 69 |
+
old_var=op.outputs[0], new_var=result)
|
| 70 |
+
function.remove_ops([op])
|
| 71 |
+
changed["fp16_token_embedding_tables"] += 1
|
| 72 |
+
if not all(changed.values()):
|
| 73 |
+
raise ValueError(f"Expected TinyGPT precision boundaries were not found: {changed}")
|
| 74 |
+
program.functions["main"].outputs[0].set_name("logits")
|
| 75 |
+
return program, changed
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
def convert(bundle, output, target=18):
|
| 79 |
+
ct = coremltools()
|
| 80 |
+
if output.exists():
|
| 81 |
+
raise ValueError("Output exists; choose a new conversion experiment.")
|
| 82 |
+
lm = BundleLM(bundle)
|
| 83 |
+
program, changed = weight_storage_graph(ct, trace_graph(lm.model), lm.model.config.context_length, target)
|
| 84 |
+
model = ct.convert(program, convert_to="mlprogram", minimum_deployment_target=getattr(ct.target, f"iOS{target}"),
|
| 85 |
+
compute_precision=ct.precision.FLOAT32, skip_model_load=True)
|
| 86 |
+
policy = {"recipe": "fp16_weights_fp32_compute_preserve_positions_qkv_v1",
|
| 87 |
+
"computation": "FP32; token embedding gather is FP16 then cast to FP32",
|
| 88 |
+
"fp16_parameters": "Token embedding; non-QKV linear weights and biases, including LM head",
|
| 89 |
+
"fp32_parameters": "Position embedding; attention QKV weights/biases; LayerNorm parameters",
|
| 90 |
+
"graph_changes": changed}
|
| 91 |
+
model.short_description = "Frozen TinyGPT; mixed FP16/FP32 weights, FP32 computation; no KV cache."
|
| 92 |
+
model.user_defined_metadata["bundle_manifest_sha256"] = lm.metadata["bundle_manifest_sha256"]
|
| 93 |
+
model.user_defined_metadata["precision_recipe"] = policy["recipe"]
|
| 94 |
+
finish(output, model, {"kind": "fp16_weights_fp32_compute", "minimum_ios": target, "bundle": lm.metadata,
|
| 95 |
+
"precision_policy": policy, "conversion_script_sha256": file_sha(Path(__file__)),
|
| 96 |
+
"interface": {"input_ids": "int32 [1,T], 1<=T<=128; right PAD only",
|
| 97 |
+
"logits": "float32 [1,T,16384]; FP32 computation; no softmax"}})
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
def parameter_compression_config(opt, model, config):
|
| 101 |
+
"""Allow only parameter matrices; global defaults must leave other consts intact."""
|
| 102 |
+
metadata = opt.get_weights_metadata(model, weight_threshold=config.weight_threshold)
|
| 103 |
+
selected, excluded = [], []
|
| 104 |
+
configs = {}
|
| 105 |
+
for name, entry in metadata.items():
|
| 106 |
+
value = entry.val
|
| 107 |
+
consumers = [{"name": child.name, "type": child.op_type,
|
| 108 |
+
"inputs": dict(child.params_name_mapping)} for child in entry.child_ops]
|
| 109 |
+
record = {"name": name, "shape": [int(dim) for dim in value.shape],
|
| 110 |
+
"dtype": str(value.dtype), "elements": int(value.size), "consumers": consumers}
|
| 111 |
+
normalized_name = name.replace(".", "_")
|
| 112 |
+
embedding = normalized_name.startswith(("model_token_embedding_weight",
|
| 113 |
+
"model_position_embedding_weight"))
|
| 114 |
+
parameter_consumers = all(
|
| 115 |
+
(child.op_type == "linear" and child.params_name_mapping.get("weight") == name) or
|
| 116 |
+
(embedding and child.op_type == "gather" and child.params_name_mapping.get("x") == name)
|
| 117 |
+
for child in entry.child_ops)
|
| 118 |
+
if (not consumers or not parameter_consumers or value.ndim != 2 or
|
| 119 |
+
not np.issubdtype(value.dtype, np.floating)):
|
| 120 |
+
record.update(reason="Not a linear weight or named embedding parameter",
|
| 121 |
+
nonfinite_elements=int((~np.isfinite(value)).sum()))
|
| 122 |
+
excluded.append(record)
|
| 123 |
+
continue
|
| 124 |
+
if value.size <= config.weight_threshold:
|
| 125 |
+
record["reason"] = "Does not exceed weight threshold"
|
| 126 |
+
excluded.append(record)
|
| 127 |
+
continue
|
| 128 |
+
if not np.isfinite(value).all():
|
| 129 |
+
raise ValueError(f"Nonfinite learned parameter {name}; refusing compression.")
|
| 130 |
+
selected.append(record)
|
| 131 |
+
configs[name] = config
|
| 132 |
+
if not selected:
|
| 133 |
+
raise ValueError("No eligible learned parameter matrices found; inspect the model graph.")
|
| 134 |
+
selection = {"policy": "linear_weights_and_named_embedding_tables_v1",
|
| 135 |
+
"selected_constants": selected, "excluded_constants": excluded,
|
| 136 |
+
"selected_elements": sum(item["elements"] for item in selected)}
|
| 137 |
+
print(f"Compression selection: {len(selected)} parameter matrices; "
|
| 138 |
+
f"{len(excluded)} large constants excluded.", flush=True)
|
| 139 |
+
for item in excluded:
|
| 140 |
+
print(f" Excluded {item['name']}: {item['reason']}", flush=True)
|
| 141 |
+
return opt.OptimizationConfig(global_config=None, op_name_configs=configs), selection
|
| 142 |
+
|
| 143 |
+
|
| 144 |
+
def compress(source, output, validation, method, bits, group_size, block_size, granularity="per_block"):
|
| 145 |
+
"""Same exact-package alignment gate, extended to this declared source kind."""
|
| 146 |
+
ct = coremltools()
|
| 147 |
+
if output.exists():
|
| 148 |
+
raise ValueError("Output exists; choose a new compression experiment.")
|
| 149 |
+
original = verify_package(source)
|
| 150 |
+
if original["kind"] != "fp16_weights_fp32_compute":
|
| 151 |
+
raise ValueError("Use this command only with an uncompressed conservative conversion.")
|
| 152 |
+
gate = read_json(validation)
|
| 153 |
+
if (gate.get("format") != "vimeml_alignment_v1" or not gate.get("passed") or
|
| 154 |
+
gate.get("coreml_manifest_sha256") != file_sha(source / "manifest.json")):
|
| 155 |
+
raise ValueError("First pass alignment for this exact source and supply its alignment.json.")
|
| 156 |
+
if method == "palette" and group_size and original["minimum_ios"] < 18:
|
| 157 |
+
raise ValueError("Grouped palette requires iOS18; use per-tensor palette or linear INT8 on iOS17.")
|
| 158 |
+
if method == "linear" and (granularity == "per_block" or bits == 4) and original["minimum_ios"] < 18:
|
| 159 |
+
raise ValueError("Blockwise/4bit linear quantization requires iOS18; use INT8 per-channel on iOS17.")
|
| 160 |
+
from coremltools.optimize import coreml as opt
|
| 161 |
+
if method == "palette":
|
| 162 |
+
try:
|
| 163 |
+
from sklearn.cluster import KMeans # noqa: F401: required by Core ML k-means fallback
|
| 164 |
+
except ImportError as error:
|
| 165 |
+
raise RuntimeError("Install the Mac requirements first; palette compression needs "
|
| 166 |
+
"scikit-learn==1.5.1 (uv pip install --python venv/coreml/bin/python "
|
| 167 |
+
"scikit-learn==1.5.1).") from error
|
| 168 |
+
model = ct.models.MLModel(str(source / "model.mlpackage"), skip_model_load=True)
|
| 169 |
+
if method == "palette":
|
| 170 |
+
config = opt.OpPalettizerConfig(mode="kmeans", nbits=bits, weight_threshold=2048,
|
| 171 |
+
granularity="per_grouped_channel" if group_size else "per_tensor", group_size=group_size or 32)
|
| 172 |
+
else:
|
| 173 |
+
config = opt.OpLinearQuantizerConfig(mode="linear_symmetric", dtype=f"int{bits}",
|
| 174 |
+
granularity=granularity, block_size=block_size if granularity == "per_block" else 0, weight_threshold=2048)
|
| 175 |
+
optimization_config, selection = parameter_compression_config(opt, model, config)
|
| 176 |
+
if method == "palette":
|
| 177 |
+
result = opt.palettize_weights(model, config=optimization_config)
|
| 178 |
+
else:
|
| 179 |
+
result = opt.linear_quantize_weights(model, config=optimization_config)
|
| 180 |
+
if not any(name.startswith("constexpr_") for name in inspect_spec(result)["operations"]):
|
| 181 |
+
raise ValueError("No compressed constexpr weights found.")
|
| 182 |
+
finish(output, result, {"kind": f"{method}{bits}_fp32_compute", "minimum_ios": original["minimum_ios"],
|
| 183 |
+
"bundle": original["bundle"], "interface": original["interface"],
|
| 184 |
+
"source_manifest_sha256": file_sha(source / "manifest.json"),
|
| 185 |
+
"fp16_alignment_sha256": file_sha(validation),
|
| 186 |
+
"conversion_script_sha256": file_sha(Path(__file__)),
|
| 187 |
+
"precision_policy": {"source_recipe": original["precision_policy"]["recipe"],
|
| 188 |
+
"computation": original["precision_policy"]["computation"]},
|
| 189 |
+
"compression": {"method": method, "bits": bits, "group_size": group_size,
|
| 190 |
+
"block_size": block_size if method == "linear" and granularity == "per_block" else None,
|
| 191 |
+
"granularity": granularity if method == "linear" else "per_grouped_channel" if group_size else "per_tensor",
|
| 192 |
+
"weight_threshold": 2048,
|
| 193 |
+
"selection": selection,
|
| 194 |
+
"scope": "Eligible learned matrices, including FP32 QKV; structural constants/masks unchanged; no activation quantization or retraining."}})
|
| 195 |
+
|
| 196 |
+
|
| 197 |
+
def main():
|
| 198 |
+
parser = argparse.ArgumentParser(description=__doc__)
|
| 199 |
+
parser.add_argument("--threads", type=int, default=4)
|
| 200 |
+
sub = parser.add_subparsers(dest="command", required=True)
|
| 201 |
+
convert_parser = sub.add_parser("convert", help="Mixed weight storage and FP32 computation, iOS18.")
|
| 202 |
+
convert_parser.add_argument("--bundle", type=Path, required=True)
|
| 203 |
+
convert_parser.add_argument("--target", type=int, choices=(17, 18), default=18)
|
| 204 |
+
compress_parser = sub.add_parser("compress", help="Compress this exact validated conservative baseline.")
|
| 205 |
+
compress_parser.add_argument("--source", type=Path, required=True)
|
| 206 |
+
compress_parser.add_argument("--fp16-alignment", type=Path, required=True)
|
| 207 |
+
compress_parser.add_argument("--method", choices=("palette", "linear"), default="palette")
|
| 208 |
+
compress_parser.add_argument("--bits", type=int, choices=(4, 8), default=4)
|
| 209 |
+
compress_parser.add_argument("--group-size", type=int, choices=(0, 8, 16, 32), default=16)
|
| 210 |
+
compress_parser.add_argument("--block-size", type=int, choices=(16, 32, 64, 128), default=32)
|
| 211 |
+
compress_parser.add_argument("--granularity", choices=("per_channel", "per_block"), default="per_block")
|
| 212 |
+
for command in (convert_parser, compress_parser):
|
| 213 |
+
command.add_argument("--output", type=Path, required=True)
|
| 214 |
+
args = parser.parse_args()
|
| 215 |
+
if args.threads < 1:
|
| 216 |
+
parser.error("threads must be positive.")
|
| 217 |
+
if args.output.exists():
|
| 218 |
+
parser.error("Output exists; use a new versioned directory.")
|
| 219 |
+
torch.set_num_threads(args.threads)
|
| 220 |
+
if args.command == "convert":
|
| 221 |
+
convert(args.bundle, args.output, args.target)
|
| 222 |
+
else:
|
| 223 |
+
compress(args.source, args.output, args.fp16_alignment, args.method, args.bits,
|
| 224 |
+
args.group_size, args.block_size, args.granularity)
|
| 225 |
+
print(f"Output: {args.output.resolve()}")
|
| 226 |
+
|
| 227 |
+
|
| 228 |
+
if __name__ == "__main__":
|
| 229 |
+
main()
|
source/scripts/deployment/package_handoff.py
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Archive Mac project snapshots, experiment evidence and Vime client for local handoff."""
|
| 2 |
+
import argparse
|
| 3 |
+
import hashlib
|
| 4 |
+
import json
|
| 5 |
+
import subprocess
|
| 6 |
+
import zipfile
|
| 7 |
+
from pathlib import Path
|
| 8 |
+
from datetime import date
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
SKIP_PARTS = {'.git', '__pycache__', '.pytest_cache', '.build', '.swiftpm', 'xcuserdata'}
|
| 12 |
+
SKIP_NAMES = {'.DS_Store'}
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def digest(source):
|
| 16 |
+
if isinstance(source, bytes):
|
| 17 |
+
return hashlib.sha256(source).hexdigest()
|
| 18 |
+
with source.open('rb') as stream:
|
| 19 |
+
return hashlib.file_digest(stream, 'sha256').hexdigest()
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def main():
|
| 23 |
+
parser = argparse.ArgumentParser(description=__doc__)
|
| 24 |
+
parser.add_argument('--project', type=Path, required=True)
|
| 25 |
+
parser.add_argument('--client', type=Path, required=True)
|
| 26 |
+
parser.add_argument('--output', type=Path, required=True)
|
| 27 |
+
args = parser.parse_args()
|
| 28 |
+
root, client, out = args.project.resolve(), args.client.resolve(), args.output.resolve()
|
| 29 |
+
if out.exists():
|
| 30 |
+
raise SystemExit('Output already exists; use a new handoff version.')
|
| 31 |
+
out.mkdir(parents=True)
|
| 32 |
+
manifest = {'format': 'vimeml_mac_handoff_v1', 'date': date.today().isoformat(),
|
| 33 |
+
'vime_git_head': subprocess.check_output(['git', 'rev-parse', 'HEAD'], cwd=client, text=True).strip(),
|
| 34 |
+
'vime_git_status': subprocess.check_output(['git', 'status', '--short'], cwd=client, text=True),
|
| 35 |
+
'archives': {}, 'excluded': [],
|
| 36 |
+
'policy': 'Local transfer only; snapshots are not automatic merge instructions or Git commits.'}
|
| 37 |
+
|
| 38 |
+
def entries(base, roots, prefix):
|
| 39 |
+
files = []
|
| 40 |
+
for name in roots:
|
| 41 |
+
source = base / name
|
| 42 |
+
if not source.exists():
|
| 43 |
+
continue
|
| 44 |
+
paths = [source] if source.is_file() else sorted(source.rglob('*'))
|
| 45 |
+
for path in paths:
|
| 46 |
+
relative = path.relative_to(base)
|
| 47 |
+
if not path.is_file():
|
| 48 |
+
continue
|
| 49 |
+
if (SKIP_PARTS.intersection(relative.parts) or path.name in SKIP_NAMES or path.suffix == '.pyc'
|
| 50 |
+
or path.name == '.env' or path.name.startswith('.env.')
|
| 51 |
+
or path.name in {'.pypirc', '.envrc'}):
|
| 52 |
+
manifest['excluded'].append(str(Path(prefix) / relative))
|
| 53 |
+
continue
|
| 54 |
+
if path.is_symlink():
|
| 55 |
+
raise SystemExit(f'Unexpected symlink requires review: {path}')
|
| 56 |
+
files.append(((Path(prefix) / relative).as_posix(), path))
|
| 57 |
+
return files
|
| 58 |
+
|
| 59 |
+
def archive(name, files):
|
| 60 |
+
indexed = []
|
| 61 |
+
with zipfile.ZipFile(out / name, 'w', compression=zipfile.ZIP_DEFLATED, compresslevel=3) as zip_file:
|
| 62 |
+
for relative, data in files:
|
| 63 |
+
value = digest(data)
|
| 64 |
+
if isinstance(data, bytes):
|
| 65 |
+
zip_file.writestr(relative, data)
|
| 66 |
+
size = len(data)
|
| 67 |
+
else:
|
| 68 |
+
zip_file.write(data, relative)
|
| 69 |
+
size = data.stat().st_size
|
| 70 |
+
indexed.append({'path': relative, 'bytes': size, 'sha256': value})
|
| 71 |
+
# Verify every entry against its source hash, including models and raw trace files.
|
| 72 |
+
with zipfile.ZipFile(out / name) as zip_file:
|
| 73 |
+
for entry in indexed:
|
| 74 |
+
with zip_file.open(entry['path']) as stream:
|
| 75 |
+
value = hashlib.file_digest(stream, 'sha256').hexdigest()
|
| 76 |
+
if value != entry['sha256']:
|
| 77 |
+
raise SystemExit(f'Archive verification failed: {entry["path"]}')
|
| 78 |
+
manifest['archives'][name] = {'file_count': len(indexed),
|
| 79 |
+
'uncompressed_bytes': sum(e['bytes'] for e in indexed),
|
| 80 |
+
'archive_bytes': (out / name).stat().st_size,
|
| 81 |
+
'entries': indexed}
|
| 82 |
+
print(f'{name}: {len(indexed)} files, {(out / name).stat().st_size / 1048576:.1f} MiB; SHA256 verified', flush=True)
|
| 83 |
+
|
| 84 |
+
source_roots = ['annotations', 'configs', 'docs', 'examples', 'scripts', 'src', 'tests']
|
| 85 |
+
source_roots += [p.name for p in root.iterdir() if p.is_file() and p.name not in SKIP_NAMES]
|
| 86 |
+
archive('VimeML-source.zip', entries(root, source_roots, 'VimeML'))
|
| 87 |
+
results_roots = ['outputs', 'runs'] + [str(p.relative_to(root)) for p in (root / 'artifacts').iterdir()
|
| 88 |
+
if p.name not in {'models', 'token-data'}]
|
| 89 |
+
archive('VimeML-results.zip', entries(root, results_roots, 'VimeML'))
|
| 90 |
+
archive('VimeML-training-inputs.zip', entries(root, ['artifacts/models', 'artifacts/token-data'], 'VimeML'))
|
| 91 |
+
|
| 92 |
+
client_paths = subprocess.check_output(['git', 'ls-files', '-z', '--cached', '--others', '--exclude-standard'], cwd=client).decode().split('\0')
|
| 93 |
+
client_entries = entries(client, sorted(set(p for p in client_paths if p)), 'Vime')
|
| 94 |
+
patch = subprocess.check_output(['git', 'diff', '--binary', 'HEAD', '--', '.', ':(exclude)**/xcuserdata/**'], cwd=client)
|
| 95 |
+
client_entries += [('CLIENT_TRACKED_CHANGES.patch', patch),
|
| 96 |
+
('CLIENT_GIT_STATUS.txt', manifest['vime_git_status'].encode()),
|
| 97 |
+
('CLIENT_GIT_HEAD.txt', (manifest['vime_git_head'] + '\n').encode()),
|
| 98 |
+
('Vime/Docs/MacStageHandoff.md', (root / 'docs/reports/mac-20261006/handoff.md').read_bytes()),
|
| 99 |
+
('Vime/Docs/iPhoneKeyboardMemory.md', (root / 'docs/reports/mac-20261006/iphone-keyboard-memory.md').read_bytes())]
|
| 100 |
+
archive('Vime-client.zip', client_entries)
|
| 101 |
+
manifest['not_archived_roots'] = ['VimeML/venv (rebuild from requirements and environment snapshot)',
|
| 102 |
+
'VimeML/handoff (this generated output)',
|
| 103 |
+
'Vime/.git (base commit and patch preserved instead)']
|
| 104 |
+
(out / 'README.md').write_bytes((root / 'docs/reports/mac-20261006/handoff.md').read_bytes())
|
| 105 |
+
(out / 'MANIFEST.json').write_text(json.dumps(manifest, ensure_ascii=False, indent=2) + '\n')
|
| 106 |
+
sums = []
|
| 107 |
+
for path in sorted(out.iterdir()):
|
| 108 |
+
if path.is_file():
|
| 109 |
+
with path.open('rb') as stream:
|
| 110 |
+
value = hashlib.file_digest(stream, 'sha256').hexdigest()
|
| 111 |
+
sums.append(f'{value} {path.name}')
|
| 112 |
+
(out / 'SHA256SUMS.txt').write_text('\n'.join(sums) + '\n')
|
| 113 |
+
print(f'Handoff ready: {out}', flush=True)
|
| 114 |
+
|
| 115 |
+
|
| 116 |
+
if __name__ == '__main__':
|
| 117 |
+
main()
|
source/scripts/deployment/package_ios.py
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Package an evaluated INT8 candidate-reranking deployment without overwriting experiments."""
|
| 2 |
+
import argparse
|
| 3 |
+
import json
|
| 4 |
+
import shutil
|
| 5 |
+
import sys
|
| 6 |
+
from pathlib import Path
|
| 7 |
+
|
| 8 |
+
ROOT = Path(__file__).resolve().parents[2]
|
| 9 |
+
sys.path.insert(0, str(ROOT / "src"))
|
| 10 |
+
from vimeml.deployment.coreml import verify_package
|
| 11 |
+
from vimeml.training.data import file_sha
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def package(source, compiled, tokenizer, review, output):
|
| 15 |
+
if output.exists():
|
| 16 |
+
raise ValueError("Output exists; choose a new deployment version.")
|
| 17 |
+
model = verify_package(source)
|
| 18 |
+
decision = json.loads(review.read_text())
|
| 19 |
+
if (model["kind"] != "linear8_fp32_compute" or model["minimum_ios"] != 18 or
|
| 20 |
+
model["compression"]["bits"] != 8 or
|
| 21 |
+
decision["source_manifest_sha256"] != file_sha(source / "manifest.json") or
|
| 22 |
+
decision["decision"] != "integrate_cpu_candidate_reranking_for_simulator_validation"):
|
| 23 |
+
raise ValueError("Review/source identity or reviewed INT8 deployment policy mismatch.")
|
| 24 |
+
if file_sha(tokenizer) != model["bundle"]["tokenizer_sha256"]:
|
| 25 |
+
raise ValueError("Wrong tokenizer for this frozen model.")
|
| 26 |
+
if not (compiled / "coremldata.bin").is_file():
|
| 27 |
+
raise ValueError("Supply an iOS18 coremlcompiler output directory.")
|
| 28 |
+
inventory = {p.relative_to(compiled).as_posix(): file_sha(p)
|
| 29 |
+
for p in sorted(compiled.rglob("*")) if p.is_file()}
|
| 30 |
+
output.mkdir(parents=True)
|
| 31 |
+
resources = output / "Resources"
|
| 32 |
+
resources.mkdir()
|
| 33 |
+
shutil.copytree(compiled, resources / "TinyJapaneseINT8.mlmodelc")
|
| 34 |
+
shutil.copyfile(tokenizer, resources / "VimeJapaneseTokenizer.model")
|
| 35 |
+
manifest = {"format": "vime_ios_lm_v1", "minimum_ios": 18, "vocab_size": 16384,
|
| 36 |
+
"context_length": 128, "compute_units": "CPU_ONLY", "tokenizer_sha256": file_sha(tokenizer),
|
| 37 |
+
"compiled_files_sha256": inventory, "source_manifest_sha256": file_sha(source / "manifest.json"),
|
| 38 |
+
"bundle_manifest_sha256": model["bundle"]["bundle_manifest_sha256"], "kind": model["kind"],
|
| 39 |
+
"quantization": decision["quantization"],
|
| 40 |
+
"strict_fp32_logits_alignment_passed": decision["strict_fp32_alignment_passed"],
|
| 41 |
+
"quality_review": "See the dated review.json; this packaging action does not validate the current client or installed device build.",
|
| 42 |
+
"integration_snapshot": "examples/ios/integration: first candidate-reranking integration, not the latest Vime client"}
|
| 43 |
+
(resources / "VimeLMManifest.json").write_text(json.dumps(manifest, ensure_ascii=False, indent=2) + "\n")
|
| 44 |
+
shutil.copyfile(review, output / "review.json")
|
| 45 |
+
shutil.copyfile(source / "manifest.json", output / "coreml-source-manifest.json")
|
| 46 |
+
shutil.copytree(ROOT / "examples/ios/VimeSentencePiece", output / "Dependencies/VimeSentencePiece")
|
| 47 |
+
shutil.copytree(ROOT / "examples/ios/integration", output / "Integration")
|
| 48 |
+
(output / "README.md").write_text("""# Vime iOS18 INT8 resource/reference package
|
| 49 |
+
|
| 50 |
+
Weight-only symmetric INT8 block32, FP32 computation, CPU_ONLY, iOS18.
|
| 51 |
+
Resources and tokenizer hashes are in Resources/VimeLMManifest.json.
|
| 52 |
+
Official SentencePiece0.2.1 and third-party license notices are preserved.
|
| 53 |
+
|
| 54 |
+
review.json is the dated first-integration review, not a fresh device acceptance.
|
| 55 |
+
Strict FP32 logits alignment failed; fixture/PAD/causal and dev/AJIMEE evidence
|
| 56 |
+
supported a limited candidate-reranking integration. Packaging does not run tests.
|
| 57 |
+
|
| 58 |
+
Integration/ is the first examples/ios/integration snapshot. It predates the latest
|
| 59 |
+
Vime client's sentence context, next-word suggestions, preferences and cancellation.
|
| 60 |
+
Use the latest Vime repository (or the archived Vime-client.zip) for those behaviors.
|
| 61 |
+
This package does not attest installed build identity, enabled settings or device stability.
|
| 62 |
+
See docs/coreml.md and docs/reports/mac-20261006/ for the subsequent device evidence.
|
| 63 |
+
""", encoding="utf-8")
|
| 64 |
+
print(output.resolve())
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
def main():
|
| 68 |
+
parser = argparse.ArgumentParser(description=__doc__)
|
| 69 |
+
for name in ("source", "compiled", "tokenizer", "review", "output"):
|
| 70 |
+
parser.add_argument("--" + name, type=Path, required=True)
|
| 71 |
+
args = parser.parse_args()
|
| 72 |
+
package(args.source, args.compiled, args.tokenizer, args.review, args.output)
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
if __name__ == "__main__":
|
| 76 |
+
main()
|
source/scripts/deployment/summarize_keyboard_trace.py
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Summarize exported Instruments sysmon-process XML for Vime processes."""
|
| 2 |
+
import argparse
|
| 3 |
+
import json
|
| 4 |
+
import statistics
|
| 5 |
+
import xml.etree.ElementTree as ET
|
| 6 |
+
from pathlib import Path
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
def summarize(source):
|
| 10 |
+
root = ET.parse(source).getroot()
|
| 11 |
+
columns = [c.findtext('mnemonic') for c in root.find('.//schema').findall('col')]
|
| 12 |
+
references = {e.attrib['id']: e for e in root.iter() if 'id' in e.attrib}
|
| 13 |
+
|
| 14 |
+
def resolve(element):
|
| 15 |
+
while 'ref' in element.attrib:
|
| 16 |
+
element = references[element.attrib['ref']]
|
| 17 |
+
return element
|
| 18 |
+
|
| 19 |
+
def number(element):
|
| 20 |
+
element = resolve(element)
|
| 21 |
+
return None if element.tag == 'sentinel' or element.text is None else float(element.text)
|
| 22 |
+
|
| 23 |
+
processes = {}
|
| 24 |
+
for row in root.findall('.//row'):
|
| 25 |
+
values = dict(zip(columns, row))
|
| 26 |
+
label = resolve(values['process']).get('fmt', '')
|
| 27 |
+
if not (label.startswith('VimeKeyboard (') or label.startswith('Vime (')):
|
| 28 |
+
continue
|
| 29 |
+
footprint = number(values['memory-physical-footprint'])
|
| 30 |
+
if footprint is None:
|
| 31 |
+
continue
|
| 32 |
+
item = {'seconds': number(values['time']) / 1e9,
|
| 33 |
+
'physical_mib': footprint / 1048576,
|
| 34 |
+
'resident_mib': number(values['memory-resident-size']) / 1048576,
|
| 35 |
+
'private_resident_mib': number(values['memory-real-private']) / 1048576,
|
| 36 |
+
'shared_resident_mib': number(values['memory-real-shared']) / 1048576,
|
| 37 |
+
'threads': number(values['thread-count']),
|
| 38 |
+
'recently_died': bool(number(values['recently-died']))}
|
| 39 |
+
processes.setdefault(label, []).append(item)
|
| 40 |
+
summary = {}
|
| 41 |
+
for label, samples in processes.items():
|
| 42 |
+
samples.sort(key=lambda s: s['seconds'])
|
| 43 |
+
peak = max(samples, key=lambda s: s['physical_mib'])
|
| 44 |
+
windows = []
|
| 45 |
+
for start in range(0, int(samples[-1]['seconds']) + 1, 30):
|
| 46 |
+
selected = [s['physical_mib'] for s in samples if start <= s['seconds'] < start + 30]
|
| 47 |
+
if selected:
|
| 48 |
+
windows.append({'start_seconds': start, 'end_seconds': start + 30,
|
| 49 |
+
'samples': len(selected), 'min_mib': min(selected),
|
| 50 |
+
'median_mib': statistics.median(selected), 'max_mib': max(selected)})
|
| 51 |
+
intervals = [b['seconds'] - a['seconds'] for a, b in zip(samples, samples[1:])]
|
| 52 |
+
summary[label] = {'sample_count': len(samples), 'first': samples[0], 'last': samples[-1],
|
| 53 |
+
'sampled_peak': peak, 'sampled_min_mib': min(s['physical_mib'] for s in samples),
|
| 54 |
+
'resident_metrics': {key: {'first_mib': samples[0][key],
|
| 55 |
+
'sampled_peak_mib': max(s[key] for s in samples),
|
| 56 |
+
'last_mib': samples[-1][key]}
|
| 57 |
+
for key in ('private_resident_mib', 'shared_resident_mib', 'resident_mib')},
|
| 58 |
+
'median_interval_seconds': statistics.median(intervals) if intervals else None,
|
| 59 |
+
'recently_died_samples': sum(s['recently_died'] for s in samples),
|
| 60 |
+
'windows': windows, 'samples': samples}
|
| 61 |
+
return {'source': str(source), 'metric': 'sysmon physical footprint; sampled peak, not lifetime high-water mark',
|
| 62 |
+
'processes': summary}
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
if __name__ == '__main__':
|
| 66 |
+
parser = argparse.ArgumentParser(description=__doc__)
|
| 67 |
+
parser.add_argument('--input', type=Path, required=True)
|
| 68 |
+
parser.add_argument('--output', type=Path, required=True)
|
| 69 |
+
args = parser.parse_args()
|
| 70 |
+
if args.output.exists():
|
| 71 |
+
parser.error("Output exists; choose a new report path.")
|
| 72 |
+
report = summarize(args.input)
|
| 73 |
+
args.output.parent.mkdir(parents=True, exist_ok=True)
|
| 74 |
+
with args.output.open('x', encoding='utf-8') as stream:
|
| 75 |
+
stream.write(json.dumps(report, indent=2) + '\n')
|
| 76 |
+
print(json.dumps({k: {key: value for key, value in v.items() if key != 'samples'}
|
| 77 |
+
for k, v in report['processes'].items()}, indent=2))
|
source/scripts/deployment/summarize_memory.py
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Summarize preserved fresh-process simulator memory audits (MiB, not iPhone estimates)."""
|
| 2 |
+
import argparse
|
| 3 |
+
import json
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
def summarize(directory):
|
| 8 |
+
reports = {name: json.loads((directory / (name + '.json')).read_text())
|
| 9 |
+
for name in ('direct', 'reload', 'engine', 'lm')}
|
| 10 |
+
repeat = directory / 'lm_words-repeat.json'
|
| 11 |
+
if repeat.exists():
|
| 12 |
+
reports['lm_words'] = json.loads(repeat.read_text())
|
| 13 |
+
rows = []
|
| 14 |
+
for name in ('engine', 'lm', 'lm_words'):
|
| 15 |
+
if name not in reports:
|
| 16 |
+
continue
|
| 17 |
+
report = reports[name]
|
| 18 |
+
steady = next(s for s in report['stages'] if s['stage'] == 'worker_cycles_61_80')['after']['physical_mib']
|
| 19 |
+
values = [x['memory']['physical_mib'] for x in report['checkpoints']]
|
| 20 |
+
rows.append({'scenario': name, 'baseline_mib': report['baseline']['physical_mib'],
|
| 21 |
+
'warm_after_80_cycles_mib': steady, 'process_peak_mib': report['final']['process_lifetime_peak_mib'],
|
| 22 |
+
'warm_checkpoints_range_mib': max(values) - min(values),
|
| 23 |
+
'after_worker_release_mib': report['final']['physical_mib'],
|
| 24 |
+
'cycles_with_suggestions': report.get('cycles_with_published_suggestions')})
|
| 25 |
+
direct = reports['direct']
|
| 26 |
+
deltas = {}
|
| 27 |
+
for phase in ('scores', 'next_words'):
|
| 28 |
+
values = [x['memory']['physical_mib'] for x in direct['checkpoints'] if x.get('stage') == phase]
|
| 29 |
+
deltas[phase + '_20_to_100_growth_mib'] = values[-1] - values[0]
|
| 30 |
+
reload_values = [x['memory']['physical_mib'] for x in reports['reload']['checkpoints']]
|
| 31 |
+
prior = json.loads((directory / 'prior-keyboard-trace.json').read_text())
|
| 32 |
+
failed = directory / 'lm_words-failed.json'
|
| 33 |
+
summary = {'scope': 'optimized iOS27.0 arm64 Simulator test host, CPU_ONLY; not actual keyboard extension',
|
| 34 |
+
'rows': rows, 'bounded_growth': deltas,
|
| 35 |
+
'reload_1_to_20_growth_mib': reload_values[-1] - reload_values[0],
|
| 36 |
+
'reload_10_to_20_growth_mib': reload_values[-1] - reload_values[9],
|
| 37 |
+
'first_lm_words_failed': failed.exists(),
|
| 38 |
+
'prior_extension_sampled_peak_mib': prior['peak_physical_mib'],
|
| 39 |
+
'prior_extension_lm_loaded_proven': False,
|
| 40 |
+
'limitations': ['Single runs with varying baselines; no fixed keyboard memory limit inferred.',
|
| 41 |
+
'No new device connection, installation or recording.',
|
| 42 |
+
'A bounded plateau does not exclude all leaks.',
|
| 43 |
+
'Prior extension trace settings/source/workload do not prove LM-active measurement.']}
|
| 44 |
+
return summary
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
if __name__ == '__main__':
|
| 48 |
+
parser = argparse.ArgumentParser(description=__doc__)
|
| 49 |
+
parser.add_argument('--directory', type=Path, required=True)
|
| 50 |
+
parser.add_argument('--output', type=Path, help='New report path; default DIRECTORY/summary.json')
|
| 51 |
+
args = parser.parse_args()
|
| 52 |
+
output = args.output or args.directory / 'summary.json'
|
| 53 |
+
if output.exists():
|
| 54 |
+
parser.error('Output exists; use --output with a new report path.')
|
| 55 |
+
report = summarize(args.directory)
|
| 56 |
+
output.parent.mkdir(parents=True, exist_ok=True)
|
| 57 |
+
with output.open('x', encoding='utf-8') as stream:
|
| 58 |
+
stream.write(json.dumps(report, indent=2) + '\n')
|
| 59 |
+
print(json.dumps(report, indent=2))
|
source/scripts/publishing/hub.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Manual Hub upload/download. Network work starts only with an explicit subcommand."""
|
| 2 |
+
import argparse
|
| 3 |
+
import json
|
| 4 |
+
import sys
|
| 5 |
+
from pathlib import Path
|
| 6 |
+
|
| 7 |
+
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
| 8 |
+
from prepare_hf import verifier
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def main():
|
| 12 |
+
parser = argparse.ArgumentParser(description=__doc__)
|
| 13 |
+
sub = parser.add_subparsers(dest='command', required=True)
|
| 14 |
+
upload = sub.add_parser('upload', help='Manually upload only the verified inventory into the existing model repo main branch.')
|
| 15 |
+
upload.add_argument('--release', type=Path, required=True)
|
| 16 |
+
download = sub.add_parser('download', help='Download a fixed Hub commit into a fresh directory, then checksum-verify.')
|
| 17 |
+
download.add_argument('--revision', required=True, help='Full 40-character Hub commit from upload output')
|
| 18 |
+
download.add_argument('--output', type=Path, required=True)
|
| 19 |
+
for command in (upload, download):
|
| 20 |
+
command.add_argument('--repo-id', default='Voltline/vimeml-tiny-ja-v1')
|
| 21 |
+
args = parser.parse_args()
|
| 22 |
+
check = verifier()
|
| 23 |
+
if args.command == 'upload':
|
| 24 |
+
manifest, files = check.verify(args.release)
|
| 25 |
+
if manifest['repo_id'] != args.repo_id:
|
| 26 |
+
parser.error('Release and target repository identities differ.')
|
| 27 |
+
from huggingface_hub import CommitOperationAdd, HfApi
|
| 28 |
+
api = HfApi()
|
| 29 |
+
parent = api.repo_info(args.repo_id, repo_type='model', revision='main').sha
|
| 30 |
+
result = api.create_commit(repo_id=args.repo_id, repo_type='model', revision='main', parent_commit=parent,
|
| 31 |
+
operations=[CommitOperationAdd(path_in_repo=name, path_or_fileobj=str(args.release / name)) for name in files],
|
| 32 |
+
commit_message='Release frozen VimeML tiny-ja-v1 FP32 and Core ML INT8 (GPL-2.0)')
|
| 33 |
+
print(json.dumps({'repo_id': args.repo_id, 'hub_commit': result.oid,
|
| 34 |
+
'commit_url': result.commit_url, 'uploaded_files': len(files)}, indent=2))
|
| 35 |
+
else:
|
| 36 |
+
if len(args.revision) != 40 or any(c not in '0123456789abcdef' for c in args.revision):
|
| 37 |
+
parser.error('Use a full immutable 40-character Hub commit, not main.')
|
| 38 |
+
if args.output.exists():
|
| 39 |
+
parser.error('Output exists; use a fresh download directory.')
|
| 40 |
+
from huggingface_hub import snapshot_download
|
| 41 |
+
snapshot_download(repo_id=args.repo_id, repo_type='model', revision=args.revision, local_dir=str(args.output))
|
| 42 |
+
manifest, files = check.verify(args.output)
|
| 43 |
+
if manifest['repo_id'] != args.repo_id:
|
| 44 |
+
raise ValueError('Downloaded release belongs to a different repository.')
|
| 45 |
+
print(json.dumps({'repo_id': args.repo_id, 'hub_commit': args.revision,
|
| 46 |
+
'verified_files': len(files), 'source_commit': manifest['source_commit']}, indent=2))
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
if __name__ == '__main__':
|
| 50 |
+
main()
|
source/scripts/publishing/prepare_hf.py
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Prepare or verify a local GPL-2.0 v1 release. Never trains, converts or uploads."""
|
| 2 |
+
import argparse
|
| 3 |
+
import importlib.util
|
| 4 |
+
import json
|
| 5 |
+
import re
|
| 6 |
+
import shutil
|
| 7 |
+
import subprocess
|
| 8 |
+
import sys
|
| 9 |
+
from datetime import datetime, timezone
|
| 10 |
+
from pathlib import Path
|
| 11 |
+
|
| 12 |
+
ROOT = Path(__file__).resolve().parents[2]
|
| 13 |
+
sys.path.insert(0, str(ROOT / 'src'))
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def verifier():
|
| 17 |
+
spec = importlib.util.spec_from_file_location('vimeml_release_verifier', ROOT / 'templates/huggingface/verify_release.py')
|
| 18 |
+
module = importlib.util.module_from_spec(spec)
|
| 19 |
+
spec.loader.exec_module(module)
|
| 20 |
+
return module
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def write_json(path, value):
|
| 24 |
+
path.parent.mkdir(parents=True, exist_ok=True)
|
| 25 |
+
path.write_text(json.dumps(value, ensure_ascii=False, indent=2, allow_nan=False) + '\n', encoding='utf-8', newline='\n')
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
def git(*args):
|
| 29 |
+
return subprocess.check_output(['git', *args], cwd=ROOT).decode('utf-8').strip()
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
def copy_checked(source, target, digest=None):
|
| 33 |
+
check = verifier()
|
| 34 |
+
source = Path(source)
|
| 35 |
+
if source.is_symlink() or not source.is_file():
|
| 36 |
+
raise ValueError(f'Expected a regular source file: {source}')
|
| 37 |
+
expected = digest or check.sha(source)
|
| 38 |
+
target.parent.mkdir(parents=True, exist_ok=True)
|
| 39 |
+
if target.exists():
|
| 40 |
+
raise ValueError(f'Refusing to overwrite: {target}')
|
| 41 |
+
shutil.copyfile(source, target)
|
| 42 |
+
if check.sha(target) != expected:
|
| 43 |
+
raise ValueError(f'Copy checksum mismatch: {target}')
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
def evaluation_summary(bundle_manifest_sha, coreml_manifest_sha):
|
| 47 |
+
from vimeml.benchmarks.evaluate_ajimee import load_export, summarize
|
| 48 |
+
from vimeml.deployment.bundle import read_json
|
| 49 |
+
from vimeml.deployment.validation import compare_rows
|
| 50 |
+
sha = verifier().sha
|
| 51 |
+
hashes, results = {}, {}
|
| 52 |
+
|
| 53 |
+
def read(path):
|
| 54 |
+
hashes[path.relative_to(ROOT).as_posix()] = sha(path)
|
| 55 |
+
return read_json(path)
|
| 56 |
+
|
| 57 |
+
def rows(path, metadata):
|
| 58 |
+
expected = metadata['files_sha256']['scores.jsonl']
|
| 59 |
+
if sha(path) != expected:
|
| 60 |
+
raise ValueError(f'Score file identity mismatch: {path}')
|
| 61 |
+
hashes[path.relative_to(ROOT).as_posix()] = expected
|
| 62 |
+
return [json.loads(line) for line in path.read_text(encoding='utf-8').splitlines()]
|
| 63 |
+
|
| 64 |
+
for role, benchmark, baseline in [('dev', 'ime-dev-v2', 'tiny-ja-v1-dev-v2-scores'),
|
| 65 |
+
('ajimee', 'ajimee-jwtd-v2-v1', 'tiny-ja-v1-ajimee')]:
|
| 66 |
+
directory = ROOT / f'outputs/deployment/conservative-int8-b32-{role}-v1'
|
| 67 |
+
report = read(directory / 'metrics.json')
|
| 68 |
+
if (report['model']['coreml_manifest_sha256'] != coreml_manifest_sha or
|
| 69 |
+
report['model']['bundle_manifest_sha256'] != bundle_manifest_sha):
|
| 70 |
+
raise ValueError('Saved evaluation uses a different model.')
|
| 71 |
+
current = rows(directory / 'scores.jsonl', report)
|
| 72 |
+
metrics = summarize(current)
|
| 73 |
+
if metrics != report['metrics']:
|
| 74 |
+
raise ValueError('Saved metrics do not match their score rows.')
|
| 75 |
+
frozen, provenance, inputs = load_export(ROOT / 'artifacts/benchmarks' / benchmark)
|
| 76 |
+
if frozen != report['benchmark_manifest'] or provenance != report['export_provenance'] or len(inputs) != len(current):
|
| 77 |
+
raise ValueError('Frozen candidate export identity changed.')
|
| 78 |
+
for left, right in zip(inputs, current):
|
| 79 |
+
if any(left[key] != right[key] for key in ('id', 'query', 'left_context', 'answers', 'candidates')):
|
| 80 |
+
raise ValueError('Saved candidate/input mismatch.')
|
| 81 |
+
prior_directory = ROOT / 'outputs/ime-eval' / baseline
|
| 82 |
+
prior_path = prior_directory / ('manifest.json' if (prior_directory / 'manifest.json').exists() else 'metrics.json')
|
| 83 |
+
prior_report = read(prior_path)
|
| 84 |
+
if any(prior_report['model'][key] != report['model'][key]
|
| 85 |
+
for key in ('checkpoint_sha256', 'tokenizer_sha256')):
|
| 86 |
+
raise ValueError('FP32 baseline belongs to different frozen weights or tokenizer.')
|
| 87 |
+
prior = rows(prior_directory / 'scores.jsonl', prior_report)
|
| 88 |
+
fp32_metrics = summarize(prior)
|
| 89 |
+
comparison = compare_rows(prior, current)
|
| 90 |
+
reported_before = prior
|
| 91 |
+
if role == 'dev':
|
| 92 |
+
source = ROOT / 'outputs/deployment/conservative-dev-v3'
|
| 93 |
+
source_metadata = read(source / 'metrics.json')
|
| 94 |
+
reported_before = rows(source / 'scores.jsonl', source_metadata)
|
| 95 |
+
if compare_rows(reported_before, current) != report['comparison']:
|
| 96 |
+
raise ValueError('Saved comparison cannot be reproduced from its actual baseline.')
|
| 97 |
+
results[role] = {'original_order': metrics['all']['azookey'],
|
| 98 |
+
'fp32_lm': fp32_metrics['all']['lm_context_sum'], 'int8_lm': metrics['all']['lm_context_sum'],
|
| 99 |
+
'windows_fp32_comparison': {k: v for k, v in comparison.items() if k != 'changes'},
|
| 100 |
+
'original_report_comparison_baseline': 'conservative Core ML' if role == 'dev' else 'Windows FP32',
|
| 101 |
+
'original_report_comparison': {k: v for k, v in report['comparison'].items() if k != 'changes'},
|
| 102 |
+
'benchmark_source_sha256': frozen['source_sha256'], 'candidate_export_sha256': provenance['files_sha256']['azookey-candidates.json']}
|
| 103 |
+
alignment = read(ROOT / 'outputs/deployment/conservative-int8-b32-alignment-v1/alignment.json')
|
| 104 |
+
if alignment['coreml_manifest_sha256'] != coreml_manifest_sha:
|
| 105 |
+
raise ValueError('Alignment belongs to a different model.')
|
| 106 |
+
distribution = read(ROOT / 'outputs/deployment/conservative-int8-b32-distribution-v1/report.json')
|
| 107 |
+
training = read(ROOT / 'artifacts/models/tiny-ja-v1/summary.json')
|
| 108 |
+
return {'format': 'vimeml_public_evaluation_v1', 'bundle_manifest_sha256': bundle_manifest_sha,
|
| 109 |
+
'coreml_manifest_sha256': coreml_manifest_sha, 'training': {
|
| 110 |
+
'prediction_targets': training['total_trained_tokens'], 'data_passes': training['completed_data_passes'],
|
| 111 |
+
'full_validation': training['full_validation']['best'], 'test_used_for_selection': False},
|
| 112 |
+
'ranking': results, 'alignment': {'strict_passed': alignment['passed'],
|
| 113 |
+
'max_logit_abs': max(row['max_abs'] for row in alignment['logits']),
|
| 114 |
+
'invariants': alignment['invariants']},
|
| 115 |
+
'distribution': {'original_report': distribution,
|
| 116 |
+
'aggregation': 'Mean of per-example position means; not corpus token-weighted.',
|
| 117 |
+
'content_token_limit': 127, 'truncation_count_recorded': False,
|
| 118 |
+
'original_report_has_full_identity_metadata': False},
|
| 119 |
+
'source_reports_sha256': hashes,
|
| 120 |
+
'scope': 'Offline fixed pools and saved Mac observations; not app-wide accuracy or a Windows Core ML runtime rerun.'}
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
def prepare(output, repo_id='Voltline/vimeml-tiny-ja-v1'):
|
| 124 |
+
output = Path(output).resolve()
|
| 125 |
+
if output.exists():
|
| 126 |
+
raise ValueError('Output exists; choose a new release version.')
|
| 127 |
+
if not re.fullmatch(r'[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+', repo_id):
|
| 128 |
+
raise ValueError('Use an OWNER/REPO model repository ID.')
|
| 129 |
+
if git('status', '--porcelain'):
|
| 130 |
+
raise ValueError('Commit the reviewed source on the current branch before preparing a release.')
|
| 131 |
+
from vimeml.deployment.bundle import verify_bundle
|
| 132 |
+
from vimeml.deployment.coreml import verify_package
|
| 133 |
+
check = verifier()
|
| 134 |
+
bundle = ROOT / 'artifacts/deployment/tiny-ja-v1-inference-v1'
|
| 135 |
+
model = ROOT / 'artifacts/deployment/tiny-ja-v1-conservative-int8-b32-v1'
|
| 136 |
+
metadata = verify_bundle(bundle)
|
| 137 |
+
coreml = verify_package(model)
|
| 138 |
+
bundle_sha, coreml_sha = check.sha(bundle / 'manifest.json'), check.sha(model / 'manifest.json')
|
| 139 |
+
if (metadata['parameter_count'] != 7386624 or coreml['kind'] != 'linear8_fp32_compute' or
|
| 140 |
+
coreml['minimum_ios'] != 18 or coreml['package_bytes'] != 8077801 or
|
| 141 |
+
coreml['bundle']['bundle_manifest_sha256'] != bundle_sha):
|
| 142 |
+
raise ValueError('Expected the reviewed frozen v1/INT8 package.')
|
| 143 |
+
summary = evaluation_summary(bundle_sha, coreml_sha)
|
| 144 |
+
for role, expected in [('dev', (137, 122, 134)), ('ajimee', (200, 124, 151))]:
|
| 145 |
+
for variant in ('fp32_lm', 'int8_lm'):
|
| 146 |
+
actual = summary['ranking'][role][variant]
|
| 147 |
+
if tuple(actual[key] for key in ('cases', 'top1_correct', 'top5_correct')) != expected:
|
| 148 |
+
raise ValueError('Saved metrics differ from this v1 model card; review before publishing.')
|
| 149 |
+
commit = git('rev-parse', 'HEAD')
|
| 150 |
+
output.mkdir(parents=True, exist_ok=False)
|
| 151 |
+
for name in [*metadata['files'], 'manifest.json']:
|
| 152 |
+
copy_checked(bundle / name, output / 'inference' / name)
|
| 153 |
+
for name, entry in coreml['package_files'].items():
|
| 154 |
+
copy_checked(model / 'model.mlpackage' / name,
|
| 155 |
+
output / 'coreml/ios18-int8-block32/model.mlpackage' / name, entry['sha256'])
|
| 156 |
+
copy_checked(model / 'manifest.json', output / 'coreml/ios18-int8-block32/manifest.json')
|
| 157 |
+
# Copy committed code/configuration, never data, annotations, artifacts or secrets.
|
| 158 |
+
source_files = subprocess.check_output(['git', 'ls-files', '-z', '--', 'src', 'scripts', 'configs',
|
| 159 |
+
'templates/huggingface', 'requirements.txt', 'LICENSE'], cwd=ROOT).decode('utf-8').split('\0')
|
| 160 |
+
for name in filter(None, source_files):
|
| 161 |
+
copy_checked(ROOT / name, output / 'source' / name)
|
| 162 |
+
(output / 'source/README.md').write_text(
|
| 163 |
+
f'VimeML source/configuration from Git commit {commit}. GPL-2.0; see LICENSE.\n'
|
| 164 |
+
'The FP32 loader checks the original model and deployment code fingerprints.\n'
|
| 165 |
+
'Corpus texts, annotations, optimizer state and the separate Vime client are not included.\n', encoding='utf-8', newline='\n')
|
| 166 |
+
copy_checked(ROOT / 'LICENSE', output / 'LICENSE')
|
| 167 |
+
for name in ('infer.py', 'verify_release.py'):
|
| 168 |
+
copy_checked(ROOT / 'templates/huggingface' / name, output / name)
|
| 169 |
+
card = (ROOT / 'templates/huggingface/README.md').read_text(encoding='utf-8')
|
| 170 |
+
for key, value in {'SOURCE_COMMIT': commit, 'BUNDLE_SHA': bundle_sha, 'COREML_SHA': coreml_sha,
|
| 171 |
+
'TOKENIZER_SHA': metadata['files']['tokenizer.model']['sha256'],
|
| 172 |
+
'CHECKPOINT_SHA': metadata['checkpoint_sha256']}.items():
|
| 173 |
+
card = card.replace(f'@@{key}@@', value)
|
| 174 |
+
if '@@' in card:
|
| 175 |
+
raise ValueError('Unresolved model card field.')
|
| 176 |
+
(output / 'README.md').write_text(card, encoding='utf-8', newline='\n')
|
| 177 |
+
write_json(output / 'evaluation/summary.json', summary)
|
| 178 |
+
files = {p.relative_to(output).as_posix(): {'bytes': p.stat().st_size, 'sha256': check.sha(p)}
|
| 179 |
+
for p in sorted(output.rglob('*')) if p.is_file()}
|
| 180 |
+
release = {'format': 'vimeml_hf_release_v1', 'repo_id': repo_id, 'license': 'gpl-2.0',
|
| 181 |
+
'source_repository': 'https://github.com/Voltline/VimeML', 'source_commit': commit,
|
| 182 |
+
'created_utc': datetime.now(timezone.utc).isoformat(), 'bundle_manifest_sha256': bundle_sha,
|
| 183 |
+
'coreml_manifest_sha256': coreml_sha, 'files': files,
|
| 184 |
+
'policy': 'Local preparation only. No training, conversion, compression, device access or upload.'}
|
| 185 |
+
write_json(output / 'RELEASE.json', release)
|
| 186 |
+
sums = {**{name: entry['sha256'] for name, entry in files.items()}, 'RELEASE.json': check.sha(output / 'RELEASE.json')}
|
| 187 |
+
(output / 'SHA256SUMS.txt').write_text(''.join(f'{digest} {name}\n' for name, digest in sorted(sums.items())),
|
| 188 |
+
encoding='utf-8', newline='\n')
|
| 189 |
+
_, verified = check.verify(output)
|
| 190 |
+
print(json.dumps({'release': str(output), 'repo_id': repo_id, 'source_commit': commit,
|
| 191 |
+
'verified_files': len(verified), 'bytes': sum((output / name).stat().st_size for name in verified)}, indent=2))
|
| 192 |
+
return release
|
| 193 |
+
|
| 194 |
+
|
| 195 |
+
def main():
|
| 196 |
+
parser = argparse.ArgumentParser(description=__doc__)
|
| 197 |
+
sub = parser.add_subparsers(dest='command', required=True)
|
| 198 |
+
build = sub.add_parser('prepare', help='Create a fresh local release from the committed source and frozen artifacts.')
|
| 199 |
+
build.add_argument('--output', type=Path, required=True)
|
| 200 |
+
build.add_argument('--repo-id', default='Voltline/vimeml-tiny-ja-v1')
|
| 201 |
+
verify = sub.add_parser('verify', help='Read-only checksum/inventory verification.')
|
| 202 |
+
verify.add_argument('--release', type=Path, required=True)
|
| 203 |
+
args = parser.parse_args()
|
| 204 |
+
if args.command == 'prepare':
|
| 205 |
+
prepare(args.output, args.repo_id)
|
| 206 |
+
else:
|
| 207 |
+
manifest, files = verifier().verify(args.release)
|
| 208 |
+
print(f"Verified {len(files)} release files for {manifest['repo_id']}")
|
| 209 |
+
|
| 210 |
+
|
| 211 |
+
if __name__ == '__main__':
|
| 212 |
+
main()
|