Text Generation
Transformers
Safetensors
Turkish
qwen3
turkish
türkçe
continued-pretraining
turkish-llm
türkçe-dil-modeli
conversational
Eval Results (legacy)
text-generation-inference
Instructions to use ecloudtech/Erk-32B with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use ecloudtech/Erk-32B with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="ecloudtech/Erk-32B") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("ecloudtech/Erk-32B") model = AutoModelForCausalLM.from_pretrained("ecloudtech/Erk-32B", device_map="auto") messages = [ {"role": "user", "content": "Who are you?"}, ] inputs = tokenizer.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=256) print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use ecloudtech/Erk-32B with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "ecloudtech/Erk-32B" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "ecloudtech/Erk-32B", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/ecloudtech/Erk-32B
- SGLang
How to use ecloudtech/Erk-32B with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "ecloudtech/Erk-32B" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "ecloudtech/Erk-32B", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "ecloudtech/Erk-32B" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "ecloudtech/Erk-32B", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use ecloudtech/Erk-32B with Docker Model Runner:
docker model run hf.co/ecloudtech/Erk-32B
Erk-32B: model karti, olcum protokolu, betikler, sonuc vektorleri
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- LICENSE +202 -0
- NOTICE +30 -0
- OLCUM-PROTOKOLU.md +395 -0
- README.md +180 -0
- betikler/birlestir.py +75 -0
- betikler/bootstrap_birlesik.py +12 -0
- betikler/bootstrap_ince.py +16 -0
- betikler/bootstrap_sft2.py +46 -0
- betikler/bootstrap_sistem.py +15 -0
- betikler/cpt32b_train.py +185 -0
- betikler/ek_sft_sinav.py +144 -0
- betikler/eval32b_heldout.py +91 -0
- betikler/gguf_uret.py +104 -0
- betikler/hata_duzeltme_uret.py +175 -0
- betikler/kimlik_sinavi_genis.py +137 -0
- betikler/kimlik_sistem_istemi.py +137 -0
- betikler/kimlik_uret.py +128 -0
- betikler/kirlilik_denetimi.py +96 -0
- betikler/kulliyat_dokumu.py +77 -0
- betikler/llama_cpp_surum.txt +1 -0
- betikler/morfbench_olcek.py +189 -0
- betikler/morfbench_olcek_v2.py +191 -0
- betikler/morfbench_zorunlu.py +186 -0
- betikler/olcek_birlesik.py +136 -0
- betikler/olcek_ince.py +136 -0
- betikler/olcek_ince_sft2.py +136 -0
- betikler/olcek_ince_sft2_ince.py +136 -0
- betikler/olcek_sistem_080.py +141 -0
- betikler/olcek_sistem_v2.py +141 -0
- betikler/olcek_taramasi.py +109 -0
- betikler/olcek_v2.py +136 -0
- betikler/permutasyon_testi.py +105 -0
- betikler/sablon_yama.py +73 -0
- betikler/sft32b_ek.py +190 -0
- betikler/sft32b_train.py +190 -0
- betikler/sft_clean.py +127 -0
- betikler/sft_repair.py +83 -0
- betikler/sohbet_talimat.py +139 -0
- sonuclar/README.md +25 -0
- sonuclar/dogrulama_ozet.json +116 -0
- sonuclar/kimlik_genis.json +144 -0
- sonuclar/kimlik_sistem.json +17 -0
- sonuclar/kirlilik_CPT.json +1 -0
- sonuclar/kirlilik_SFT.json +1 -0
- sonuclar/morfbench_v2_erk32b-sft2_o040.json +1 -0
- sonuclar/morfbench_v2_erk32b-sft2_o075.json +1 -0
- sonuclar/morfbench_v2_erk32b-sft2_o080.json +1 -0
- sonuclar/morfbench_zorunlu_erk32b-sft2_o080.json +1 -0
- sonuclar/morfbench_zorunlu_sft.json +1 -0
- sonuclar/olcek_birlesik_075.json +1 -0
LICENSE
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
Apache License
|
| 3 |
+
Version 2.0, January 2004
|
| 4 |
+
http://www.apache.org/licenses/
|
| 5 |
+
|
| 6 |
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
| 7 |
+
|
| 8 |
+
1. Definitions.
|
| 9 |
+
|
| 10 |
+
"License" shall mean the terms and conditions for use, reproduction,
|
| 11 |
+
and distribution as defined by Sections 1 through 9 of this document.
|
| 12 |
+
|
| 13 |
+
"Licensor" shall mean the copyright owner or entity authorized by
|
| 14 |
+
the copyright owner that is granting the License.
|
| 15 |
+
|
| 16 |
+
"Legal Entity" shall mean the union of the acting entity and all
|
| 17 |
+
other entities that control, are controlled by, or are under common
|
| 18 |
+
control with that entity. For the purposes of this definition,
|
| 19 |
+
"control" means (i) the power, direct or indirect, to cause the
|
| 20 |
+
direction or management of such entity, whether by contract or
|
| 21 |
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
| 22 |
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
| 23 |
+
|
| 24 |
+
"You" (or "Your") shall mean an individual or Legal Entity
|
| 25 |
+
exercising permissions granted by this License.
|
| 26 |
+
|
| 27 |
+
"Source" form shall mean the preferred form for making modifications,
|
| 28 |
+
including but not limited to software source code, documentation
|
| 29 |
+
source, and configuration files.
|
| 30 |
+
|
| 31 |
+
"Object" form shall mean any form resulting from mechanical
|
| 32 |
+
transformation or translation of a Source form, including but
|
| 33 |
+
not limited to compiled object code, generated documentation,
|
| 34 |
+
and conversions to other media types.
|
| 35 |
+
|
| 36 |
+
"Work" shall mean the work of authorship, whether in Source or
|
| 37 |
+
Object form, made available under the License, as indicated by a
|
| 38 |
+
copyright notice that is included in or attached to the work
|
| 39 |
+
(an example is provided in the Appendix below).
|
| 40 |
+
|
| 41 |
+
"Derivative Works" shall mean any work, whether in Source or Object
|
| 42 |
+
form, that is based on (or derived from) the Work and for which the
|
| 43 |
+
editorial revisions, annotations, elaborations, or other modifications
|
| 44 |
+
represent, as a whole, an original work of authorship. For the purposes
|
| 45 |
+
of this License, Derivative Works shall not include works that remain
|
| 46 |
+
separable from, or merely link (or bind by name) to the interfaces of,
|
| 47 |
+
the Work and Derivative Works thereof.
|
| 48 |
+
|
| 49 |
+
"Contribution" shall mean any work of authorship, including
|
| 50 |
+
the original version of the Work and any modifications or additions
|
| 51 |
+
to that Work or Derivative Works thereof, that is intentionally
|
| 52 |
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
| 53 |
+
or by an individual or Legal Entity authorized to submit on behalf of
|
| 54 |
+
the copyright owner. For the purposes of this definition, "submitted"
|
| 55 |
+
means any form of electronic, verbal, or written communication sent
|
| 56 |
+
to the Licensor or its representatives, including but not limited to
|
| 57 |
+
communication on electronic mailing lists, source code control systems,
|
| 58 |
+
and issue tracking systems that are managed by, or on behalf of, the
|
| 59 |
+
Licensor for the purpose of discussing and improving the Work, but
|
| 60 |
+
excluding communication that is conspicuously marked or otherwise
|
| 61 |
+
designated in writing by the copyright owner as "Not a Contribution."
|
| 62 |
+
|
| 63 |
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
| 64 |
+
on behalf of whom a Contribution has been received by Licensor and
|
| 65 |
+
subsequently incorporated within the Work.
|
| 66 |
+
|
| 67 |
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
| 68 |
+
this License, each Contributor hereby grants to You a perpetual,
|
| 69 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 70 |
+
copyright license to reproduce, prepare Derivative Works of,
|
| 71 |
+
publicly display, publicly perform, sublicense, and distribute the
|
| 72 |
+
Work and such Derivative Works in Source or Object form.
|
| 73 |
+
|
| 74 |
+
3. Grant of Patent License. Subject to the terms and conditions of
|
| 75 |
+
this License, each Contributor hereby grants to You a perpetual,
|
| 76 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 77 |
+
(except as stated in this section) patent license to make, have made,
|
| 78 |
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
| 79 |
+
where such license applies only to those patent claims licensable
|
| 80 |
+
by such Contributor that are necessarily infringed by their
|
| 81 |
+
Contribution(s) alone or by combination of their Contribution(s)
|
| 82 |
+
with the Work to which such Contribution(s) was submitted. If You
|
| 83 |
+
institute patent litigation against any entity (including a
|
| 84 |
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
| 85 |
+
or a Contribution incorporated within the Work constitutes direct
|
| 86 |
+
or contributory patent infringement, then any patent licenses
|
| 87 |
+
granted to You under this License for that Work shall terminate
|
| 88 |
+
as of the date such litigation is filed.
|
| 89 |
+
|
| 90 |
+
4. Redistribution. You may reproduce and distribute copies of the
|
| 91 |
+
Work or Derivative Works thereof in any medium, with or without
|
| 92 |
+
modifications, and in Source or Object form, provided that You
|
| 93 |
+
meet the following conditions:
|
| 94 |
+
|
| 95 |
+
(a) You must give any other recipients of the Work or
|
| 96 |
+
Derivative Works a copy of this License; and
|
| 97 |
+
|
| 98 |
+
(b) You must cause any modified files to carry prominent notices
|
| 99 |
+
stating that You changed the files; and
|
| 100 |
+
|
| 101 |
+
(c) You must retain, in the Source form of any Derivative Works
|
| 102 |
+
that You distribute, all copyright, patent, trademark, and
|
| 103 |
+
attribution notices from the Source form of the Work,
|
| 104 |
+
excluding those notices that do not pertain to any part of
|
| 105 |
+
the Derivative Works; and
|
| 106 |
+
|
| 107 |
+
(d) If the Work includes a "NOTICE" text file as part of its
|
| 108 |
+
distribution, then any Derivative Works that You distribute must
|
| 109 |
+
include a readable copy of the attribution notices contained
|
| 110 |
+
within such NOTICE file, excluding those notices that do not
|
| 111 |
+
pertain to any part of the Derivative Works, in at least one
|
| 112 |
+
of the following places: within a NOTICE text file distributed
|
| 113 |
+
as part of the Derivative Works; within the Source form or
|
| 114 |
+
documentation, if provided along with the Derivative Works; or,
|
| 115 |
+
within a display generated by the Derivative Works, if and
|
| 116 |
+
wherever such third-party notices normally appear. The contents
|
| 117 |
+
of the NOTICE file are for informational purposes only and
|
| 118 |
+
do not modify the License. You may add Your own attribution
|
| 119 |
+
notices within Derivative Works that You distribute, alongside
|
| 120 |
+
or as an addendum to the NOTICE text from the Work, provided
|
| 121 |
+
that such additional attribution notices cannot be construed
|
| 122 |
+
as modifying the License.
|
| 123 |
+
|
| 124 |
+
You may add Your own copyright statement to Your modifications and
|
| 125 |
+
may provide additional or different license terms and conditions
|
| 126 |
+
for use, reproduction, or distribution of Your modifications, or
|
| 127 |
+
for any such Derivative Works as a whole, provided Your use,
|
| 128 |
+
reproduction, and distribution of the Work otherwise complies with
|
| 129 |
+
the conditions stated in this License.
|
| 130 |
+
|
| 131 |
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
| 132 |
+
any Contribution intentionally submitted for inclusion in the Work
|
| 133 |
+
by You to the Licensor shall be under the terms and conditions of
|
| 134 |
+
this License, without any additional terms or conditions.
|
| 135 |
+
Notwithstanding the above, nothing herein shall supersede or modify
|
| 136 |
+
the terms of any separate license agreement you may have executed
|
| 137 |
+
with Licensor regarding such Contributions.
|
| 138 |
+
|
| 139 |
+
6. Trademarks. This License does not grant permission to use the trade
|
| 140 |
+
names, trademarks, service marks, or product names of the Licensor,
|
| 141 |
+
except as required for reasonable and customary use in describing the
|
| 142 |
+
origin of the Work and reproducing the content of the NOTICE file.
|
| 143 |
+
|
| 144 |
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
| 145 |
+
agreed to in writing, Licensor provides the Work (and each
|
| 146 |
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
| 147 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
| 148 |
+
implied, including, without limitation, any warranties or conditions
|
| 149 |
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
| 150 |
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
| 151 |
+
appropriateness of using or redistributing the Work and assume any
|
| 152 |
+
risks associated with Your exercise of permissions under this License.
|
| 153 |
+
|
| 154 |
+
8. Limitation of Liability. In no event and under no legal theory,
|
| 155 |
+
whether in tort (including negligence), contract, or otherwise,
|
| 156 |
+
unless required by applicable law (such as deliberate and grossly
|
| 157 |
+
negligent acts) or agreed to in writing, shall any Contributor be
|
| 158 |
+
liable to You for damages, including any direct, indirect, special,
|
| 159 |
+
incidental, or consequential damages of any character arising as a
|
| 160 |
+
result of this License or out of the use or inability to use the
|
| 161 |
+
Work (including but not limited to damages for loss of goodwill,
|
| 162 |
+
work stoppage, computer failure or malfunction, or any and all
|
| 163 |
+
other commercial damages or losses), even if such Contributor
|
| 164 |
+
has been advised of the possibility of such damages.
|
| 165 |
+
|
| 166 |
+
9. Accepting Warranty or Additional Liability. While redistributing
|
| 167 |
+
the Work or Derivative Works thereof, You may choose to offer,
|
| 168 |
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
| 169 |
+
or other liability obligations and/or rights consistent with this
|
| 170 |
+
License. However, in accepting such obligations, You may act only
|
| 171 |
+
on Your own behalf and on Your sole responsibility, not on behalf
|
| 172 |
+
of any other Contributor, and only if You agree to indemnify,
|
| 173 |
+
defend, and hold each Contributor harmless for any liability
|
| 174 |
+
incurred by, or claims asserted against, such Contributor by reason
|
| 175 |
+
of your accepting any such warranty or additional liability.
|
| 176 |
+
|
| 177 |
+
END OF TERMS AND CONDITIONS
|
| 178 |
+
|
| 179 |
+
APPENDIX: How to apply the Apache License to your work.
|
| 180 |
+
|
| 181 |
+
To apply the Apache License to your work, attach the following
|
| 182 |
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
| 183 |
+
replaced with your own identifying information. (Don't include
|
| 184 |
+
the brackets!) The text should be enclosed in the appropriate
|
| 185 |
+
comment syntax for the file format. We also recommend that a
|
| 186 |
+
file or class name and description of purpose be included on the
|
| 187 |
+
same "printed page" as the copyright notice for easier
|
| 188 |
+
identification within third-party archives.
|
| 189 |
+
|
| 190 |
+
Copyright [yyyy] [name of copyright owner]
|
| 191 |
+
|
| 192 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
| 193 |
+
you may not use this file except in compliance with the License.
|
| 194 |
+
You may obtain a copy of the License at
|
| 195 |
+
|
| 196 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
| 197 |
+
|
| 198 |
+
Unless required by applicable law or agreed to in writing, software
|
| 199 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
| 200 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 201 |
+
See the License for the specific language governing permissions and
|
| 202 |
+
limitations under the License.
|
NOTICE
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Erk-32B
|
| 2 |
+
Copyright (c) 2026 eCloud Yazılım Teknolojileri (eCloud Tech.)
|
| 3 |
+
|
| 4 |
+
This model is a derivative work of Qwen3-32B
|
| 5 |
+
(https://huggingface.co/Qwen/Qwen3-32B), Copyright (c) Alibaba Cloud,
|
| 6 |
+
licensed under the Apache License, Version 2.0. The base model's architecture,
|
| 7 |
+
tokenizer and chat format are unchanged; eCloud Tech. modified the weights by
|
| 8 |
+
continued pretraining on Turkish text (1.05B tokens, LoRA r=256), Turkish
|
| 9 |
+
instruction tuning (423M tokens) and an additional instruction round, then
|
| 10 |
+
merged the adapter at scale 0.75 and added a default identity system prompt to
|
| 11 |
+
the chat template. Details: OLCUM-PROTOKOLU.md.
|
| 12 |
+
|
| 13 |
+
Erk-32B is distributed under the Apache License, Version 2.0 (see LICENSE).
|
| 14 |
+
|
| 15 |
+
"Erk" and "eCloud Tech." are names and marks of eCloud Yazılım Teknolojileri.
|
| 16 |
+
This license does not grant permission to use them to endorse or promote
|
| 17 |
+
derived products without prior written permission, except as required for
|
| 18 |
+
reasonable and customary attribution.
|
| 19 |
+
|
| 20 |
+
--------------------------------------------------------------------------
|
| 21 |
+
Erk-32B
|
| 22 |
+
Telif (c) 2026 eCloud Yazılım Teknolojileri (eCloud Tech.)
|
| 23 |
+
|
| 24 |
+
Bu model, Apache Lisansı 2.0 ile dağıtılan Qwen3-32B'nin (Alibaba Cloud)
|
| 25 |
+
türev çalışmasıdır. Mimari, tokenizer ve sohbet biçimi tabandan gelir;
|
| 26 |
+
eCloud Tech. ağırlıkları Türkçe devam-eğitimi, talimat ayarı ve ek turla
|
| 27 |
+
değiştirmiş, adaptörü 0,75 ölçeğiyle birleştirmiş ve sohbet şablonuna
|
| 28 |
+
varsayılan kimlik istemi eklemiştir. Erk-32B, Apache Lisansı 2.0 ile dağıtılır.
|
| 29 |
+
"Erk" ve "eCloud Tech." adları eCloud Yazılım Teknolojileri'ne aittir; bu
|
| 30 |
+
lisans marka kullanım hakkı vermez.
|
OLCUM-PROTOKOLU.md
ADDED
|
@@ -0,0 +1,395 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Erk-32B — Teknik Rapor ve Ölçüm Protokolü
|
| 2 |
+
|
| 3 |
+
**Durum:** 8 Eylül 2026 · devam-eğitimi, talimat ayarı ve ek talimat turu
|
| 4 |
+
tamamlandı. Morfoloji kıyasının ilk sürümünde altın cevap hataları bulundu;
|
| 5 |
+
tüm morfoloji sayıları düzeltilmiş v2 ile yeniden ölçüldü (4.2). Çalışma
|
| 6 |
+
noktası **0,75 + kimlik sistem istemi** (4.2'de gerekçe; 0,40 kararı istemli
|
| 7 |
+
karşılaştırma ölçülünce geri alındı). Henüz yayımlanmadı.
|
| 8 |
+
|
| 9 |
+
Bu belge, Erk-32B için üretilen her sayının nasıl ölçüldüğünü ve hangi
|
| 10 |
+
elemelerden geçtiğini kayda geçirir. Amaç, sonuçların bağımsız olarak
|
| 11 |
+
yeniden üretilebilmesi ve eleştiriye ölçümle cevap verilebilmesidir.
|
| 12 |
+
|
| 13 |
+
---
|
| 14 |
+
|
| 15 |
+
## 1. Model ve eğitim
|
| 16 |
+
|
| 17 |
+
| | |
|
| 18 |
+
|---|---|
|
| 19 |
+
| Taban | Qwen3-32B (bize ait değildir, her yerde belirtilir) |
|
| 20 |
+
| Devam-eğitimi | 1,05B Türkçe token · LoRA r=256 α=512 · 32.000 adım |
|
| 21 |
+
| Talimat ayarı | 423M token · 12.909 adım · 2 tur |
|
| 22 |
+
| Ek talimat turu | 46.000 örnek (kimlik 6.000 + morfolojik hata düzeltme 40.000) · 1.673 adım · temiz külliyata karıştırılarak |
|
| 23 |
+
| Yayın ağırlığı | LoRA 0,75 ile birleştirilmiş, 14 parça safetensors, 62 GB (`erk32b-birlesik-075`); GGUF Q8_0 ve Q4_K_M |
|
| 24 |
+
| Donanım | 4×A100-80GB · FSDP · bf16 |
|
| 25 |
+
| Toplam hesap | ≈37.000 çekirdek-saat |
|
| 26 |
+
|
| 27 |
+
**Çalışma noktası:** LoRA katkısı **0,75** ölçeğiyle uygulanır
|
| 28 |
+
(`W = W_taban + 0,75 × LoRA`) ve kimlik sohbet şablonundaki **varsayılan
|
| 29 |
+
sistem istemiyle** verilir. Gerekçesi 4.2'de.
|
| 30 |
+
|
| 31 |
+
---
|
| 32 |
+
|
| 33 |
+
## 2. Külliyat dökümü
|
| 34 |
+
|
| 35 |
+
**Devam-eğitimi (1,32B token, 4,30 GB)**
|
| 36 |
+
|
| 37 |
+
| | |
|
| 38 |
+
|---|---|
|
| 39 |
+
| Kaynak | Türkçe web külliyatı, akış sırasıyla ilk 4 GB |
|
| 40 |
+
| Belge | 1.354.261 |
|
| 41 |
+
| Dil doğrulaması | %96,83 Türkçe · %0,49 İngilizce · %2,67 belirsiz |
|
| 42 |
+
| Yaklaşık tekrar | %1,37 |
|
| 43 |
+
| Belge uzunluğu | medyan 1.603 B · %90: 5.739 · %99: 24.541 |
|
| 44 |
+
|
| 45 |
+
**Talimat ayarı (373.387 örnek)**
|
| 46 |
+
|
| 47 |
+
Ham külliyatta 453.975 örnek vardı. Denetimde, gerçek kod içeren 38.637
|
| 48 |
+
cevabın **%53,5'inin makine çevirisiyle bozulduğu** ölçüldü: sözdizimi
|
| 49 |
+
kelime kelime Türkçeleştirilmiş (`using namespace std;` → "ad alanı
|
| 50 |
+
std'sini kullanma;"), kod bloğu dil etiketleri çevrilmiş.
|
| 51 |
+
|
| 52 |
+
Temizlik: 7.703 bozuk sözdizimi + 12.983 çitsiz kod + 42.330 kopya +
|
| 53 |
+
2.910 kimlik beyanı + 14.567 çok kısa cevap elendi. Etiketi çevrilmiş
|
| 54 |
+
blokların içindeki kod %100 sağlam olduğu için silinmedi, **onarıldı**
|
| 55 |
+
(4.888 örnek kurtarıldı).
|
| 56 |
+
|
| 57 |
+
Talimat külliyatında kıyas kirliliği: **n=13 katı eşikte 0/900.**
|
| 58 |
+
|
| 59 |
+
---
|
| 60 |
+
|
| 61 |
+
## 3. Ölçüm protokolü
|
| 62 |
+
|
| 63 |
+
Ham ölçümlerin büyük kısmı ölçüm yapaylığı çıktı. Aşağıdaki elemeler
|
| 64 |
+
uygulanmadan hiçbir sayı raporlanmaz.
|
| 65 |
+
|
| 66 |
+
### 3.1 Seçim sızıntısı
|
| 67 |
+
Eğitim sırasında izlenen 150 soru rapordan hariç → held-out 750.
|
| 68 |
+
|
| 69 |
+
### 3.2 Kirlilik
|
| 70 |
+
Kıyas sorularının metni eğitim külliyatında 13-kelimelik pencerelerle aranır.
|
| 71 |
+
|
| 72 |
+
| Eşik | Kirli | Held-out 750 içinde |
|
| 73 |
+
|---|---|---|
|
| 74 |
+
| n=13 (katı) | 113/900 (%12,6) | 98 |
|
| 75 |
+
| n=8 (gevşek) | 252/900 (%28,0) | 211 |
|
| 76 |
+
|
| 77 |
+
Beklenen bir sonuçtur: web külliyatı ile sınav soruları aynı kaynaklarda
|
| 78 |
+
bulunur. Karşılaştırılan taban modelin de benzer veriyi görmüş olması
|
| 79 |
+
muhtemeldir; bu yüzden kirli sorular **her iki model için de** atılır.
|
| 80 |
+
Raporlanan küme: **temiz 652**.
|
| 81 |
+
|
| 82 |
+
Atılmazsa fark ~2 puan şişer (+6,27 → +4,14).
|
| 83 |
+
|
| 84 |
+
Not: denetim sorunun **metninin** külliyatta geçtiğini gösterir, cevap
|
| 85 |
+
anahtarının sızdığını değil. %12,6 bir üst sınırdır.
|
| 86 |
+
|
| 87 |
+
### 3.3 Harf/konum önyargısı
|
| 88 |
+
Şıklar dairesel döndürülür, doğru cevap yeni harfine taşınır. Etkisi
|
| 89 |
+
ölçüldü: kirli sorularda orijinal sırayla 16,33 puanlık fark,
|
| 90 |
+
döndürüldüğünde 6,12'ye düşüp anlamlılığını yitirdi.
|
| 91 |
+
|
| 92 |
+
### 3.4 Biçim uyumu
|
| 93 |
+
Üretimli ölçüm, talimat-ayarsız modellerde bilgi değil biçim uyumu ölçer.
|
| 94 |
+
Morfoloji kıyasında üretimli fark **+36,17**'ydi; ham çıktılarda taban
|
| 95 |
+
modelin ya sustuğu ya İngilizce akıl yürütmeye kaydığı görüldü.
|
| 96 |
+
Zorunlu-seçim (öğretmen-zorlamalı log-olabilirlik) ile aynı fark **+3,73**.
|
| 97 |
+
|
| 98 |
+
### 3.5 Üretim uzunluğu
|
| 99 |
+
Sohbet biçiminde taban model önce düşünme bloğu üretir, cevap sonra gelir.
|
| 100 |
+
Kısa token sınırı bu modelleri blok ortasında kesip "cevap veremedi"
|
| 101 |
+
gösteriyordu (24 token ile taban %0). Blok için yer bırakılır, cevap
|
| 102 |
+
bloğun ardından aranır, kesilen örnek sayısı ayrıca raporlanır.
|
| 103 |
+
|
| 104 |
+
### 3.6 İstatistik
|
| 105 |
+
Her fark için eşleştirilmiş bootstrap (10.000 yeniden örnekleme) ile %95
|
| 106 |
+
güven aralığı verilir. Aralık sıfırı içeriyorsa "fark yok" değil, **"bu
|
| 107 |
+
örneklemle gösteremiyoruz"** denir.
|
| 108 |
+
|
| 109 |
+
---
|
| 110 |
+
|
| 111 |
+
## 4. Çalışma noktasının seçimi
|
| 112 |
+
|
| 113 |
+
Devam-eğitimi sonrası ölçümde bir kusur bulundu: model sohbet biçiminde
|
| 114 |
+
cevap veremiyordu. 329 örneğin **tamamında** üretimi durdurmadan web
|
| 115 |
+
metni üretmeye devam etti (örnek: çoğul sorusuna haber metniyle karşılık).
|
| 116 |
+
Talimat ayarı bunu onardı ama taban modelin seviyesine çıkaramadı
|
| 117 |
+
(%54,71 vs %60,49).
|
| 118 |
+
|
| 119 |
+
LoRA toplanabilir olduğu için, yeniden eğitim yapmadan ölçek taraması
|
| 120 |
+
yapıldı. Sekiz nokta, iki eksende, soru-bazlı vektörlerle:
|
| 121 |
+
|
| 122 |
+
| Ölçek | Sohbet (n=329) | Kıyas (n=652) | Kıyas farkı vs taban |
|
| 123 |
+
|---|---|---|---|
|
| 124 |
+
| 0,00 (taban) | %60,49 | %67,64 | — |
|
| 125 |
+
| 0,15 | %62,61 | %70,71 | +3,07 [+0,92, +5,37] |
|
| 126 |
+
| 0,20 | %64,13 | %70,86 | +3,22 [+0,77, +5,67] |
|
| 127 |
+
| 0,25 | %62,92 | %71,32 | +3,68 [+1,38, +6,13] |
|
| 128 |
+
| 0,30 | %62,61 | %72,55 | +4,91 [+2,30, +7,52] |
|
| 129 |
+
| 0,35 | %57,45 | %72,85 | +5,21 [+2,61, +7,82] |
|
| 130 |
+
| **0,40** | **%63,22** | **%73,16** | **+5,52 [+2,76, +8,28]** |
|
| 131 |
+
| 0,50 | %58,05 | %72,55 | +4,91 [+2,30, +7,67] |
|
| 132 |
+
| 1,00 (tam güç) | %54,71 | %71,01 | — |
|
| 133 |
+
|
| 134 |
+
**Sohbet ekseninde hiçbir ölçek tabandan istatistiksel olarak farklı
|
| 135 |
+
değildir** (sekiz güven aralığının hepsi sıfırı içerir). Kıyas ekseninde
|
| 136 |
+
hepsi anlamlı derecede iyidir.
|
| 137 |
+
|
| 138 |
+
İlk seçim (30 Ağustos): **0,40** — kıyas farkının en yüksek olduğu nokta,
|
| 139 |
+
sohbet kaybı yok. Tam güce (1,00) göre kıyas farkı +2,15 [−0,15, +4,45];
|
| 140 |
+
anlamlı değildir.
|
| 141 |
+
|
| 142 |
+
### 4.1 Ek talimat turu sonrası tarama (7 Eylül) — v1 kıyasıyla, tarihçe
|
| 143 |
+
|
| 144 |
+
*Bu bölümdeki "sohbet" sütunu TurkMorfBench **v1** üretim ölçümüdür. v1'in
|
| 145 |
+
altın cevaplarında 18 hata bulunmuş (4.2), sayılar v2 ile yeniden ölçülmüştür.
|
| 146 |
+
Bölüm, seçimin nasıl değiştiğini göstermek için korunur; karar 4.2'dedir.*
|
| 147 |
+
|
| 148 |
+
Ek tur (kimlik + hata düzeltme) sonrası aynı iki eksen, on iki ölçek:
|
| 149 |
+
|
| 150 |
+
| Ölçek | Sohbet (n=329) | Kıyas (n=652) | Kesik | Kimlik (30 soru) |
|
| 151 |
+
|---|---|---|---|---|
|
| 152 |
+
| 0,00 (taban) | %60,49 | %67,64 | 329 | — |
|
| 153 |
+
| 0,40 | %60,18 | **%73,47** | 176 | — |
|
| 154 |
+
| 0,70 | %59,57 | %71,47 | 128 | 6/30 |
|
| 155 |
+
| 0,75 | %66,87 | %71,47 | 16 | 8/30 |
|
| 156 |
+
| **0,80** | **%69,00** | %71,01 | 0 | 12/30 |
|
| 157 |
+
| 0,85 | %63,22 | %71,63 | 0 | 15/30 |
|
| 158 |
+
| 0,90 | %62,01 | %71,63 | 0 | 19/30 |
|
| 159 |
+
| 0,95 | %62,92 | %71,63 | 0 | 22/30 |
|
| 160 |
+
| 1,00 | %61,70 | %71,47 | 0 | 28/30 |
|
| 161 |
+
|
| 162 |
+
Eşli bootstrap (10.000, tabana karşı): sohbet 0,75 +6,38 [+0,61, +11,85] ve
|
| 163 |
+
0,80 +8,51 [+2,43, +14,29]; 0,85'te fark kaybolur (+2,74 [−3,95, +9,42]) ve
|
| 164 |
+
0,80 vs 0,85 anlamlıdır (+5,78 [+2,43, +9,12]). **Sohbet ekseninde tabandan
|
| 165 |
+
anlamlı derecede iyi bir bölge ilk kez ortaya çıkmıştır: 0,75–0,80 platosu.**
|
| 166 |
+
Kıyas 0,70–1,00 arasında düzdür; 0,40 bu bölgeden +2,45 [+0,46, +4,45]
|
| 167 |
+
öndedir.
|
| 168 |
+
|
| 169 |
+
Ek tur 0,40'ta hiçbir şeyi değiştirmemiştir (sohbet −3,04 [−6,69, +0,91],
|
| 170 |
+
kıyas +0,31 [−0,46, +1,07]); tam ölçekteki sohbet düşüşünü onarmıştır
|
| 171 |
+
(1,00'da %54,71 → %61,70).
|
| 172 |
+
|
| 173 |
+
**Kimlik.** Ağırlıklara işlenen kimlik keskin eşikle değil rampayla gelir ve
|
| 174 |
+
ancak 1,00'da oturur (28/30; kalan iki hata: "Erya", "540 milyar
|
| 175 |
+
parametre"). Sistem istemiyle 0,40, 0,80 ve 1,00'da **30/30**, tuzak
|
| 176 |
+
sorular dahil. İstemin sohbet bedeli 0,80'de −1,52 [−5,47, +2,13],
|
| 177 |
+
anlamsız; kıyas istemi ham metin olduğu için etkilenmez.
|
| 178 |
+
|
| 179 |
+
**Hata düzeltme öğrenilmemiştir.** Serbest metinde morfolojik hata bulma,
|
| 180 |
+
eğitimde kullanılmayan gövdelerle 8 cümlede her ölçekte 4/8 — taban ile
|
| 181 |
+
aynı. 40.000 örnek ölçülebilir etki bırakmamıştır; görev ezber değil
|
| 182 |
+
genelleme istemektedir.
|
| 183 |
+
|
| 184 |
+
7 Eylül'deki seçim 0,80 idi: v1 üretim ekseninde 0,80'in 0,40'a +8,81
|
| 185 |
+
[+3,34, +14,29] üstünlüğü görünüyordu. Bu fark v1'in altın cevap hatalarının
|
| 186 |
+
ürünü çıktı (4.2); seçim geri alındı.
|
| 187 |
+
|
| 188 |
+
### 4.2 Düzeltilmiş kıyasla yeniden ölçüm ve nihai seçim (8 Eylül)
|
| 189 |
+
|
| 190 |
+
**Ne bulundu.** TurkMorfBench v1'de (329 madde) gerçek gövdelerde 18 yanlış
|
| 191 |
+
altın cevap vardı: yönelme ekinde yumuşama hiç uygulanmamış (*çocuka, kitapa,
|
| 192 |
+
ağaça*), iyelikte her p/ç/t/k gövdesi yumuşatılmış (*südü, buludu, renği*);
|
| 193 |
+
uydurma gövdelerde tek bir kural yoktu. Ayrıca zorunlu seçimin az-örnekli
|
| 194 |
+
istemi kıyas gövdelerini (*kalem, defter, bardak*) kullanıyordu. Düzeltilmiş
|
| 195 |
+
v2 (512 madde, 8 görev, 40 gerçek + 24 uydurma gövde) bağımsız kural
|
| 196 |
+
tablosuyla 512/512 doğrulandı, az-örnek gövdeleri kıyas dışından seçildi
|
| 197 |
+
(*tahta, sepet, sandalye, kabak*) ve morfolojiye dayanan her sayı yeniden
|
| 198 |
+
ölçüldü.
|
| 199 |
+
|
| 200 |
+
**Üretim (talimat izleme), v2, n=512:**
|
| 201 |
+
|
| 202 |
+
| Ölçek | Üretim | Fark vs taban | Kıyas (652) |
|
| 203 |
+
|---|---|---|---|
|
| 204 |
+
| 0,00 (taban) | %31,64 | — | %67,64 |
|
| 205 |
+
| **0,40** | %55,86 | +24,22 [+18,95, +29,49] | **%73,47** |
|
| 206 |
+
| 0,75 | **%61,52** | +29,88 [+24,61, +35,16] | %71,47 |
|
| 207 |
+
| 0,80 | %57,42 | +25,78 [+20,51, +31,05] | %71,01 |
|
| 208 |
+
| 0,85 | %56,25 | | %71,63 |
|
| 209 |
+
| 1,00 | %46,09 | | %71,47 |
|
| 210 |
+
| 0,40 + sistem istemi | %49,02 | +17,38 [+11,91, +22,85] | %73,47 |
|
| 211 |
+
| 0,75 + sistem istemi | %59,38 | +27,73 [+22,46, +33,01] | %71,47 |
|
| 212 |
+
| 0,80 + sistem istemi | %56,05 | | %71,01 |
|
| 213 |
+
|
| 214 |
+
İstemsiz noktalar arası: 0,80 vs 0,40 +1,56 [−3,32, +6,45] gösterilemedi
|
| 215 |
+
(v1'de +8,81 idi); 0,75 vs 0,40 +5,66 [+0,98, +10,35] anlamlı.
|
| 216 |
+
|
| 217 |
+
**Sistem isteminin bedeli ölçeğe bağlı:** 0,40'ta −6,84 [−11,53, −1,95]
|
| 218 |
+
(anlamlı), 0,75'te −2,15 [−6,05, +1,56] (gösterilemedi). Dağıtım
|
| 219 |
+
yapılandırması istemli olduğu için karşılaştırma istemli noktalar arasında
|
| 220 |
+
yapılmalıdır: **0,75 + istem vs 0,40 + istem +10,35 [+5,47, +15,43] anlamlı;
|
| 221 |
+
0,80 + istem vs 0,40 + istem +7,03 [+2,15, +11,91] anlamlı.** Kıyasta 0,40 vs
|
| 222 |
+
0,80 +2,45 [+0,46, +4,45] anlamlı; 0,40 vs 0,75 +1,99 [+0,00, +3,99] sınırda.
|
| 223 |
+
(Önceki taslakta 0,75 + istem, 0,40 *istemsiz* ile karşılaştırılmış ve fark
|
| 224 |
+
gösterilememişti; o karşılaştırma yapılandırmaları eşleştirmiyordu.)
|
| 225 |
+
|
| 226 |
+
**Zorunlu seçim, v2, n=502 (312 gerçek, 190 uydurma), az-örnek sızıntısız:**
|
| 227 |
+
|
| 228 |
+
| Ölçek | Toplam | Gerçek | Uydurma |
|
| 229 |
+
|---|---|---|---|
|
| 230 |
+
| taban | %89,44 | %94,55 | %81,05 |
|
| 231 |
+
| 0,40 | %89,84 · +0,40 [−1,20, +2,19] | %95,19 · +0,64 [−0,64, +1,92] | %81,05 · 0,00 |
|
| 232 |
+
| 0,75 | %91,43 · +1,99 [−0,20, +4,18] | %96,47 · +1,92 [−0,32, +4,17] | %83,16 · +2,11 [−2,11, +6,32] |
|
| 233 |
+
| 0,80 | %91,83 · +2,39 [+0,20, +4,78] | %97,12 · +2,56 [+0,64, +4,81] | %83,16 · +2,11 [−2,63, +6,84] |
|
| 234 |
+
|
| 235 |
+
v1'deki "+3,73 anlamlı" morfoloji üstünlüğü v2'de yoktur: 0,40'ta fark
|
| 236 |
+
gösterilemez, 0,80'de küçük ve sınırdadır, uydurma gövdelerde hiçbir noktada
|
| 237 |
+
gösterilemez. Devam-eğitimi Türkçe bilgiyi artırmış, ek sistemini ölçülebilir
|
| 238 |
+
biçimde değiştirmemiştir.
|
| 239 |
+
|
| 240 |
+
**Kimlik**: sistem istemiyle 0,40 / 0,75 / 0,80 / 1,00 → 30/30.
|
| 241 |
+
|
| 242 |
+
**Nihai seçim: 0,75 + sistem istemi.** Bu protokolün kuralı, aralığı sıfırı
|
| 243 |
+
içeren farkın gösterilemediğidir. Dağıtım yapılandırmasında (istemli)
|
| 244 |
+
0,75, üretimde 0,40'ı +10,35 [+5,47, +15,43] ile anlamlı geçer; 0,40'ın
|
| 245 |
+
kıyastaki üstünlüğü +1,99 [+0,00, +3,99] ile gösterilemez. Kimlik her
|
| 246 |
+
noktada tamdır. Önceki taslak 0,40'ı seçmişti; o seçim 0,75 + istemi 0,40
|
| 247 |
+
istemsizle karşılaştıran eşleşmeyen bir kıyasa dayanıyordu ve 0,40 + istem
|
| 248 |
+
ölçülünce (%49,02) geri alındı. Başlık sayısı 0,75'in sayısıdır; 0,40 ve
|
| 249 |
+
0,80 satırları tabloda kalır.
|
| 250 |
+
|
| 251 |
+
---
|
| 252 |
+
|
| 253 |
+
## 5. Sonuçlar
|
| 254 |
+
|
| 255 |
+
**Kıyas bilgisi** (TurkishMMLU, temiz 652, döndürülmüş)
|
| 256 |
+
|
| 257 |
+
| Model | Doğruluk |
|
| 258 |
+
|---|---|
|
| 259 |
+
| Taban Qwen3-14B | %60,58 |
|
| 260 |
+
| Erk-14B (aynı protokol; kendi kartında tam küme, döndürmesiz 0-shot: %69,7) | %67,18 |
|
| 261 |
+
| Taban Qwen3-32B | %67,64 |
|
| 262 |
+
| Erk-32B (0,40, ek tur öncesi) | %73,16 |
|
| 263 |
+
| Erk-32B (0,40, LoRA yolu) | %73,47 |
|
| 264 |
+
| Erk-32B (0,40, birleşik; önceki aday) | %73,16 |
|
| 265 |
+
| Erk-32B (0,75, LoRA yolu) | %71,47 |
|
| 266 |
+
| **Erk-32B (0,75, yayınlanan birleşik ağırlık)** | **%71,01** |
|
| 267 |
+
|
| 268 |
+
Birleştirme (`W = W_taban + 0,75 × LoRA`, fp32 çarpım, tek bf16 yuvarlama)
|
| 269 |
+
aynı ölçüm betiğiyle yeniden ölçüldü: LoRA yoluyla 652 sorunun 649'unda,
|
| 270 |
+
329 üretim maddesinin 313'ünde aynı cevap; farklar −0,46 [−1,07, +0,00] ve
|
| 271 |
+
0,00 [−2,43, +2,43], yuvarlama yolu. Başlık sayısı yayınlanan ağırlığın kendi
|
| 272 |
+
ölçümüdür.
|
| 273 |
+
|
| 274 |
+
| Karşılaştırma | Fark | %95 GA |
|
| 275 |
+
|---|---|---|
|
| 276 |
+
| **Erk-32B (birleşik 0,75) vs kendi tabanı** | **+3,37** | **[+0,61, +6,13]** |
|
| 277 |
+
| Erk-32B (LoRA yolu 0,75) vs kendi tabanı | +3,83 | [+0,92, +6,90] |
|
| 278 |
+
| Erk-32B (LoRA yolu 0,40) vs kendi tabanı | +5,83 | [+3,22, +8,44] |
|
| 279 |
+
| Erk-32B LoRA 0,40 vs birleşik 0,75 | +2,45 | [+0,46, +4,60] |
|
| 280 |
+
| Erk-32B LoRA 0,40 vs LoRA 0,75 | +1,99 | [+0,00, +3,99] gösterilemedi |
|
| 281 |
+
| Erk-32B 0,40 vs 0,80 | +2,45 | [+0,46, +4,45] |
|
| 282 |
+
| Erk-14B vs kendi tabanı | +6,60 | [+3,07, +10,28] |
|
| 283 |
+
| Taban 32B vs taban 14B (ölçek etkisi) | +7,06 | [+3,53, +10,74] |
|
| 284 |
+
|
| 285 |
+
**Morfoloji** (TurkMorfBench v2, zorunlu seçim, 502 madde; az-örnek gövdeleri
|
| 286 |
+
kıyas dışından)
|
| 287 |
+
|
| 288 |
+
| Küme | Taban | **Erk-32B (0,75)** | Fark | %95 GA |
|
| 289 |
+
|---|---|---|---|---|
|
| 290 |
+
| Toplam (502) | %89,44 | %91,43 | +1,99 | [−0,20, +4,18] gösterilemedi |
|
| 291 |
+
| Gerçek kelime (312) | %94,55 | %96,47 | +1,92 | [−0,32, +4,17] gösterilemedi |
|
| 292 |
+
| Uydurma kelime (190) | %81,05 | %83,16 | +2,11 | [−2,11, +6,32] gösterilemedi |
|
| 293 |
+
|
| 294 |
+
İşletme noktasında morfoloji farkı **gösterilememektedir** (alt sınırlar
|
| 295 |
+
sıfırın hemen altında). v1 kıyasıyla raporlanmış olan +3,73 [+0,93, +6,83]
|
| 296 |
+
değeri altın cevap hatalarının ürünüdür (4.2, 8. bölüm). 0,80'de küçük bir
|
| 297 |
+
fark görülür (+2,39 [+0,20, +4,78]); 0,40'ta hiç yoktur (+0,40).
|
| 298 |
+
|
| 299 |
+
Uydurma kelime testi kuralın **üretkenliğini** ölçer; hiçbir ölçekte fark
|
| 300 |
+
gösterilememiştir. Bulgu: devam-eğitimi Türkçe bilgiyi geliştirmiş, ek
|
| 301 |
+
sistemini ölçülebilir biçimde değiştirmemiştir. Örneklem küçüktür (n=190,
|
| 302 |
+
±3,7); "fark yok" değil, "gösterilemiyor" geçerlidir.
|
| 303 |
+
|
| 304 |
+
**Üretim (talimat izleme)** (TurkMorfBench v2, 512 madde, tam eşleşme,
|
| 305 |
+
dağıtım yapılandırması = sistem istemli): taban %31,64 → Erk-32B 0,75 + istem
|
| 306 |
+
**%59,38**, +27,73 [+22,46, +33,01]. Bu eksen bilgiyle birlikte biçime uymayı
|
| 307 |
+
ölçer; taban model düşünme bloğunda kalıp cevap vermediği için düşüktür.
|
| 308 |
+
|
| 309 |
+
**Kimlik** (30 soru, tuzak sorular dahil): 0,75 + sistem istemi 30/30.
|
| 310 |
+
|
| 311 |
+
---
|
| 312 |
+
|
| 313 |
+
## 6. Bilinen sınırlar
|
| 314 |
+
|
| 315 |
+
1. **Tek tohum.** Tüm sonuçlar tek eğitim koşusundan. Bootstrap aralıkları
|
| 316 |
+
soru örneklemesinin belirsizliğini kapsar, eğitim tohumununkini kapsamaz.
|
| 317 |
+
32B ölçeğinde çok tohumlu koşu mevcut bütçeyle mümkün değildir.
|
| 318 |
+
2. **Taban model bize ait değildir.**
|
| 319 |
+
3. **Kirlilik üst sınırı** — denetim soru metnini arar, cevap anahtarını değil.
|
| 320 |
+
4. **Taban modelin külliyatı denetlenemez.** Karşılaştırma "temiz vs kirli"
|
| 321 |
+
değil, iki tarafın da bilinmeyen ölçüde kirli olduğu varsayımıyla yapılır.
|
| 322 |
+
5. **Morfoloji kıyasının kapsamı** kurallı gövdelerle sınırlıdır; ünlü
|
| 323 |
+
düşmesi gibi sözlüksel istisnalar bilinçli olarak dışarıda bırakılmıştır.
|
| 324 |
+
6. **Ölçüm sayısı sınırlıdır**: iki eksen (çoktan seçmeli bilgi, morfoloji)
|
| 325 |
+
ve bir kullanılabilirlik testi. Üretim kalitesi, uzun bağlam, kod, akıl
|
| 326 |
+
yürütme ölçülmemiştir.
|
| 327 |
+
7. **Kimlik sistem istemine bağlıdır.** Ağırlıklardaki kimlik 0,75'te
|
| 328 |
+
30 soruda 8/30, 0,80'de 12/30'dur; istemsiz dağıtımda model taban
|
| 329 |
+
modelin kimliğini söyler.
|
| 330 |
+
Şablon varsayılan istemi taşır; kullanıcı kendi sistem mesajını verirse
|
| 331 |
+
varsayılan devreye girmez.
|
| 332 |
+
8. **Morfoloji kazancı gösterilememiştir.** İlk sürüm kıyasıyla raporlanan
|
| 333 |
+
fark altın cevap hatalarıydı; v2'de 0,75'te alt sınır sıfırın altındadır.
|
| 334 |
+
9. **İşletme noktası iki kez değişti** (0,40 → 0,80 → 0,40 → 0,75). Her
|
| 335 |
+
değişiklik bir ölçüm hatasının düzeltilmesinden geldi (4.1, 4.2, 8. bölüm);
|
| 336 |
+
eğrinin kendisi tek checkpoint'ten ve tek tohumdandır.
|
| 337 |
+
10. **Üretim ekseni morfoloji sorularıyla sınırlıdır.** "Talimat izleme"
|
| 338 |
+
genel sohbet kalitesi değil, morfoloji sorularına biçime uyarak cevap
|
| 339 |
+
verme oranıdır.
|
| 340 |
+
|
| 341 |
+
---
|
| 342 |
+
|
| 343 |
+
## 7. Yeniden üretim
|
| 344 |
+
|
| 345 |
+
| Aşama | Betik |
|
| 346 |
+
|---|---|
|
| 347 |
+
| Külliyat dökümü | `kulliyat_dokumu.py` |
|
| 348 |
+
| SFT denetimi ve temizliği | `sft_clean.py`, `sft_repair.py` |
|
| 349 |
+
| Devam-eğitimi | `cpt32b_train.py` |
|
| 350 |
+
| Talimat ayarı | `sft32b_train.py` |
|
| 351 |
+
| Kirlilik denetimi | `kirlilik_denetimi.py` |
|
| 352 |
+
| Kıyas ölçümü | `eval32b_heldout.py` |
|
| 353 |
+
| Permütasyon testi | `permutasyon_testi.py` |
|
| 354 |
+
| Morfoloji (zorunlu seçim) | `morfbench_zorunlu.py` |
|
| 355 |
+
| Talimat izleme | `sohbet_talimat.py` |
|
| 356 |
+
| Ölçek taraması | `olcek_ince.py` |
|
| 357 |
+
| Ek tur sonrası tarama | `olcek_ince_sft2.py`, `olcek_ince_sft2_ince.py`, `olcek_sistem_080.py` |
|
| 358 |
+
| v2 taraması ve istemli noktalar | `olcek_v2.py`, `olcek_sistem_v2.py` (0,80), `_075`, `_040` türevleri; `bootstrap_sis040.py` |
|
| 359 |
+
| GGUF üretim ve doğrulama | `gguf_uret.py` (BF16 → Q8_0, Q4_K_M; kimlik + NLL), `sablon_yama.py` (varsayılan kimlik istemi) |
|
| 360 |
+
| Kimlik sınavı (30 soru) | `kimlik_sinavi_genis.py`, `kimlik_sistem_istemi.py` |
|
| 361 |
+
| Eşli bootstrap | `bootstrap_sft2.py`, `bootstrap_ince.py`, `bootstrap_sistem.py`, `bootstrap_birlesik.py` |
|
| 362 |
+
| Morfoloji, ölçekli | `morfbench_olcek.py` (CK_DIR, OLCEK) |
|
| 363 |
+
| Birleştirme ve doğrulama | `birlestir.py`, `olcek_birlesik.py` |
|
| 364 |
+
|
| 365 |
+
Tüm ölçüm çıktıları soru-bazlı tahmin vektörleriyle JSON olarak saklanır;
|
| 366 |
+
eşleştirilmiş karşılaştırmalar modeli yeniden çalıştırmadan yapılabilir.
|
| 367 |
+
|
| 368 |
+
---
|
| 369 |
+
|
| 370 |
+
## 8. Ölçüm günlüğü — düzeltilen sayılar
|
| 371 |
+
|
| 372 |
+
Bu bölüm, ham ölçümlerin neden doğrudan raporlanmadığını gösterir.
|
| 373 |
+
|
| 374 |
+
| Ham sayı | Sebep | Düzeltilmiş |
|
| 375 |
+
|---|---|---|
|
| 376 |
+
| +6,27 | kirli sorular dahildi | +4,14 |
|
| 377 |
+
| +36,17 | biçim uyumu bilgi sanıldı | +3,73 |
|
| 378 |
+
| +53,80 | üretim token sınırında kesildi | ölçülemez |
|
| 379 |
+
| 7.171 saat (EEG) | sinyalsiz dosyalar sayıldı | 5.247 saat |
|
| 380 |
+
| −5,78 (sohbet kaybı) | ölçek 1,00'da ölçüldü | 0,40'ta kayıp yok |
|
| 381 |
+
| −1,69 (ek tur "gerilemesi") | 1,00 sonucu 0,40 sonucuyla kıyaslandı | aynı ölçekte +0,46, gürültü |
|
| 382 |
+
| kimlik 1/5 | sınav 0,40'ta, kimlik 1,00'da öğrenilmişti | 1,00'da 28/30; istemle 30/30 |
|
| 383 |
+
| kimlik "2/5, kısmi" (0,80) | 5 soruluk sınav | 30 soruda 12/30 |
|
| 384 |
+
| %71,01 (0,80 kıyas) | LoRA yolu; birleşik ağırlık değil | birleşik %71,32, 650/652 aynı (yuvarlama) |
|
| 385 |
+
| %73,47 (0,40 kıyas) | LoRA yolu; yayınlanan birleşik ağırlık değil | birleşik %73,16, 646/652 aynı (yuvarlama) |
|
| 386 |
+
| %71,47 (0,75 kıyas) | LoRA yolu; yayınlanan birleşik ağırlık değil | birleşik %71,01, 649/652 aynı (yuvarlama) |
|
| 387 |
+
| +3,73 morfoloji (v1) | kıyasın 18 altın cevabı yanlıştı | v2'de +0,40, gösterilemedi |
|
| 388 |
+
| +8,81 (0,80 vs 0,40 üretim, v1) | aynı altın cevap hataları | v2'de +1,56, gösterilemedi; seçim 0,40'a döndü |
|
| 389 |
+
| +3,52 "gösterilemedi" (0,75+istem vs 0,40) | istemli nokta istemsizle kıyaslanmıştı | 0,40+istem %49,02; 0,75+istem vs 0,40+istem +10,35 [+5,47, +15,43]; seçim 0,75 |
|
| 390 |
+
| GGUF kimlik 4/6 | denetleyici "ben ChatGPT değilim" cevabında adı sayıyordu | kural düzeltildi, 6/6 (üç nicem) |
|
| 391 |
+
| zorunlu seçim az-örnek istemi | kalem/defter/bardak kıyas gövdesiydi | kıyas dışı gövdelerle yeniden ölçüldü |
|
| 392 |
+
| "kesik" sütunu | yığın-bazlı sayım, üst sınır | kaldırıldı |
|
| 393 |
+
|
| 394 |
+
Hiçbiri dışarıdan bildirilmedi; hepsi yayımdan önce kendi denetimimizde
|
| 395 |
+
bulundu.
|
README.md
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: apache-2.0
|
| 3 |
+
language:
|
| 4 |
+
- tr
|
| 5 |
+
base_model: Qwen/Qwen3-32B
|
| 6 |
+
pipeline_tag: text-generation
|
| 7 |
+
library_name: transformers
|
| 8 |
+
tags:
|
| 9 |
+
- turkish
|
| 10 |
+
- türkçe
|
| 11 |
+
- qwen3
|
| 12 |
+
- continued-pretraining
|
| 13 |
+
- lora
|
| 14 |
+
- turkish-llm
|
| 15 |
+
- türkçe-dil-modeli
|
| 16 |
+
- gguf
|
| 17 |
+
model-index:
|
| 18 |
+
- name: Erk-32B
|
| 19 |
+
results:
|
| 20 |
+
- task:
|
| 21 |
+
type: multiple-choice
|
| 22 |
+
name: TurkishMMLU (temiz-652, şık döndürmeli)
|
| 23 |
+
dataset:
|
| 24 |
+
name: TurkishMMLU
|
| 25 |
+
type: AYueksel/TurkishMMLU
|
| 26 |
+
metrics:
|
| 27 |
+
- type: accuracy
|
| 28 |
+
value: 71.01
|
| 29 |
+
name: doğruluk (temiz 652)
|
| 30 |
+
---
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
# Erk-32B — Türkçe dil modeli, ölçüm protokolüyle
|
| 34 |
+
|
| 35 |
+
Erk-32B, açık kaynaklı **Qwen3-32B** temel modeli üzerine 1,05 milyar token Türkçe
|
| 36 |
+
devam-eğitimi ve 423 milyon token Türkçe talimat ayarı uygulanarak eCloud Tech.
|
| 37 |
+
tarafından geliştirilmiş bir Türkçe dil modelidir. Bu sayfadaki her sayı,
|
| 38 |
+
**kirlilik denetimi, şık döndürme, zorunlu seçim ve eşli bootstrap güven
|
| 39 |
+
aralığı** elemelerinden geçmiştir; ölçüm protokolü, düzeltilen ham sayılar ve
|
| 40 |
+
yeniden üretim betikleri depoda açıktır.
|
| 41 |
+
|
| 42 |
+
*English summary at the end.*
|
| 43 |
+
|
| 44 |
+
## Sonuçlar (işletme noktası: LoRA ölçeği 0,75 + sistem istemi, birleşik ağırlık)
|
| 45 |
+
|
| 46 |
+
| Ölçüm | Taban Qwen3-32B | **Erk-32B** | Fark | %95 GA |
|
| 47 |
+
|---|---|---|---|---|
|
| 48 |
+
| TurkishMMLU, temiz 652, şık döndürmeli | %67,64 | **%71,01** | +3,37 | [+0,61, +6,13] |
|
| 49 |
+
| TurkMorfBench v2 üretim (512, tam eşleşme, sistem istemli) | %31,64 | **%59,38** | +27,73 | [+22,46, +33,01] |
|
| 50 |
+
| TurkMorfBench v2 zorunlu seçim, toplam (502) | %89,44 | %91,43 | +1,99 | [−0,20, +4,18] gösterilemedi |
|
| 51 |
+
| TurkMorfBench v2 zorunlu seçim, gerçek kelime (312) | %94,55 | %96,47 | +1,92 | [−0,32, +4,17] gösterilemedi |
|
| 52 |
+
| TurkMorfBench v2 zorunlu seçim, uydurma (190) | %81,05 | %83,16 | +2,11 | [−2,11, +6,32] gösterilemedi |
|
| 53 |
+
| Kimlik (30 soru, tuzaklı, sistem istemli) | — | **30/30** | | |
|
| 54 |
+
|
| 55 |
+
Aynı protokolde ölçek karşılaştırması (temiz 652): Qwen3-14B %60,58 · Erk-14B
|
| 56 |
+
%67,18 · Qwen3-32B %67,64 · Erk-32B %71,01. (Birleşik ağırlık LoRA yoluyla
|
| 57 |
+
649/652 aynı cevap; 0,40 ölçeğinde %73,47 — kıyasta sınırda daha iyi, üretimde
|
| 58 |
+
10 puan geri; iki nokta da raporda.) [Erk-14B'nin kendi kartındaki
|
| 59 |
+
%69,7](https://huggingface.co/ecloudtech/Erk-14B), tam kümede, şık döndürmesiz,
|
| 60 |
+
lm-evaluation-harness 0-shot ölçümüdür; buradaki %67,18 aynı modelin kirlilik
|
| 61 |
+
dışı bırakılmış, döndürülmüş ölçümüdür. Fark protokolden gelir, modelden değil.
|
| 62 |
+
|
| 63 |
+
Ne **söylemiyoruz**: morfoloji bilgisinde (zorunlu seçim) tabandan fark
|
| 64 |
+
gösterilemedi — alt sınırlar sıfırın hemen altında, uydurma gövdelerde hiç.
|
| 65 |
+
Devam-eğitimi Türkçe *bilgiyi* geliştirmiş, ek sistemini ölçülebilir biçimde
|
| 66 |
+
değiştirmemiştir. Üretim eksenindeki +28 puan büyük ölçüde biçim uyumudur
|
| 67 |
+
(taban model düşünme bloğunda kalıp cevap yazmıyor). Tek eğitim tohumu; güven
|
| 68 |
+
aralıkları soru örneklemesini kapsar, tohumu kapsamaz.
|
| 69 |
+
|
| 70 |
+
## İşletme noktası nasıl seçildi
|
| 71 |
+
|
| 72 |
+
LoRA toplamsal olduğu için (`W = W_taban + s · LoRA`) ölçek *s* eğitim sonrası
|
| 73 |
+
bir ayar düğmesidir. On iki noktada üç eksen ölçüldü; kimlik sistem istemiyle
|
| 74 |
+
verildiğinden karşılaştırma **istemli** noktalar arasında yapıldı. Üretimde
|
| 75 |
+
0,75 + istem, 0,40 + istemi +10,35 [+5,47, +15,43] ile anlamlı geçer; kıyasta
|
| 76 |
+
0,40'ın üstünlüğü +1,99 [+0,00, +3,99] ile gösterilemez. Aralığı sıfırı
|
| 77 |
+
içeren fark bu protokolde "gösterilemedi" sayıldığından **0,75** seçildi;
|
| 78 |
+
0,40 ve 0,80 satırları raporda durur. Ayrıntı: `OLCUM-PROTOKOLU.md` §4.2.
|
| 79 |
+
|
| 80 |
+
## Kimlik ve sistem istemi
|
| 81 |
+
|
| 82 |
+
Kimlik ağırlıklara işlenmemiştir; sohbet şablonundaki **varsayılan sistem
|
| 83 |
+
istemi** ile verilir. Kullanıcı kendi sistem mesajını verirse varsayılan
|
| 84 |
+
devreye girmez. İstem, taban modeli açıkça söyler:
|
| 85 |
+
|
| 86 |
+
> Sen Erk-32B'sin: eCloud Tech. tarafından, açık kaynaklı Qwen3-32B temel modeli
|
| 87 |
+
> üzerine Türkçe devam-eğitimi ve talimat ayarıyla geliştirilmiş 32 milyar
|
| 88 |
+
> parametreli bir Türkçe dil modelisin. …
|
| 89 |
+
|
| 90 |
+
## Kullanım
|
| 91 |
+
|
| 92 |
+
```python
|
| 93 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 94 |
+
m = "ecloudtech/Erk-32B"
|
| 95 |
+
tok = AutoTokenizer.from_pretrained(m)
|
| 96 |
+
model = AutoModelForCausalLM.from_pretrained(m, torch_dtype="auto", device_map="auto")
|
| 97 |
+
msgs = [{"role": "user", "content": "Türkçede ünsüz yumuşaması nedir? /no_think"}]
|
| 98 |
+
ids = tok.apply_chat_template(msgs, add_generation_prompt=True, return_tensors="pt").to(model.device)
|
| 99 |
+
print(tok.decode(model.generate(ids, max_new_tokens=300)[0][ids.shape[1]:], skip_special_tokens=True))
|
| 100 |
+
```
|
| 101 |
+
|
| 102 |
+
Qwen3 hibrit düşünme modu korunur: `/no_think` ile kapatılır. GGUF sürümleri
|
| 103 |
+
(Q8_0, Q4_K_M) llama.cpp / Ollama / LM Studio ile çalışır; nicemleme
|
| 104 |
+
doğrulaması (kimlik ve NLL) model kartının sonundadır.
|
| 105 |
+
|
| 106 |
+
## Eğitim
|
| 107 |
+
|
| 108 |
+
| | |
|
| 109 |
+
|---|---|
|
| 110 |
+
| Taban | Qwen3-32B (Apache 2.0) |
|
| 111 |
+
| Devam-eğitimi | 1,05B Türkçe web token · LoRA r=256 α=512 · 32.000 adım |
|
| 112 |
+
| Talimat ayarı | 423M token, 373.387 örnek (temizlenmiş) · 2 tur |
|
| 113 |
+
| Ek tur | kimlik 6.000 + morfolojik hata düzeltme 40.000 · 1.673 adım |
|
| 114 |
+
| Donanım | 4×A100-80GB, FSDP, bf16 · ≈37.000 çekirdek-saat |
|
| 115 |
+
| Yayın ağırlığı | LoRA 0,75 ile birleştirilmiş (fp32 çarpım, tek bf16 yuvarlama); LoRA yoluyla eşdeğerlik aynı ölçüm betiğiyle doğrulanır |
|
| 116 |
+
| GGUF | Q8_0 34,8 GB (NLL +%0,04) · Q4_K_M 19,8 GB (NLL +%0,85); BF16 referansına göre, 6.132 belirteçlik Türkçe metinde; her nicemde kimlik 6/6 |
|
| 117 |
+
|
| 118 |
+
Talimat külliyatında kod içeren cevapların %53,5'i makine çevirisiyle bozuktu;
|
| 119 |
+
temizlik ve onarım betikleri depodadır. Talimat külliyatında kıyas kirliliği
|
| 120 |
+
n=13 eşiğinde 0/900.
|
| 121 |
+
|
| 122 |
+
## Ölçüm protokolü — kısa
|
| 123 |
+
|
| 124 |
+
1. **Kirlilik**: TurkishMMLU'nun 900 sorusundan 113'ü devam-eğitimi külliyatında
|
| 125 |
+
birebir geçiyor (13-kelime pencere); bunlar ve 150 soruluk ayar kümesi
|
| 126 |
+
dışarıda → temiz 652. Liste: `turkishmmlu-kirlilik` deposu.
|
| 127 |
+
2. **Şık döndürme**: her soru şık sırası döndürülerek ölçülür; harf/konum
|
| 128 |
+
yanlılığı elenir.
|
| 129 |
+
3. **Zorunlu seçim vs üretim**: biçim uyumu bilgiden ayrılır (üretimde +28
|
| 130 |
+
puan görünen fark zorunlu seçimde +2,0, gösterilemedi).
|
| 131 |
+
5. **Kıyasın kendisi denetlenir**: morfoloji kıyasının ilk sürümünde 18 yanlış
|
| 132 |
+
altın cevap bulundu; tüm sayılar düzeltilmiş v2 ile yeniden ölçüldü ve v1
|
| 133 |
+
ile raporlanmış +3,73'lük "morfoloji üstünlüğü" geri çekildi.
|
| 134 |
+
4. **Eşli bootstrap**: 10.000 yeniden örnekleme; aralığı sıfırı içeren fark
|
| 135 |
+
"gösterilemedi" olarak yazılır.
|
| 136 |
+
|
| 137 |
+
Düzeltilen ham sayıların günlüğü (`OLCUM-PROTOKOLU.md` §8) on iki kalem içerir;
|
| 138 |
+
hiçbiri dışarıdan bildirilmedi.
|
| 139 |
+
|
| 140 |
+
## Sınırlar
|
| 141 |
+
|
| 142 |
+
- Tek tohum; tohumlar arası varyans ölçülmedi.
|
| 143 |
+
- Üretim kalitesi, uzun bağlam, kod ve akıl yürütme ölçülmedi.
|
| 144 |
+
- Kimlik sistem istemine bağlıdır; istemsiz dağıtımda model taban modelin kimliğini söyler.
|
| 145 |
+
- Morfoloji bilgisinde kazanç gösterilememiştir; üretim eksenindeki fark biçim uyumunu içerir.
|
| 146 |
+
- Taban modelin külliyatı denetlenemez; karşılaştırma iki tarafın da bilinmeyen ölçüde kirli olduğu varsayımıyla yapılır.
|
| 147 |
+
|
| 148 |
+
## Depo içeriği
|
| 149 |
+
|
| 150 |
+
`OLCUM-PROTOKOLU.md` tam rapor (8 bölüm, ölçüm günlüğü dahil) · `betikler/`
|
| 151 |
+
eğitim, temizlik, ölçüm, tarama, bootstrap, birleştirme ve GGUF betikleri (34
|
| 152 |
+
dosya, llama.cpp sürümü sabitlenmiş) · `sonuclar/` soru-bazlı tahmin vektörleri
|
| 153 |
+
(17 JSON; eşli karşılaştırmalar model çalıştırmadan yeniden yapılabilir) ·
|
| 154 |
+
`README-GGUF.md` nicemlenmiş sürümlerin kartı. Kardeş depolar:
|
| 155 |
+
**TurkMorfBench** (kıyas + üretici + denetim betikleri) ve **TurkishMMLU
|
| 156 |
+
kirlilik listesi**.
|
| 157 |
+
|
| 158 |
+
Lisans Apache 2.0 (taban modelle aynı). İletişim: info@e-cloud.web.tr
|
| 159 |
+
|
| 160 |
+
---
|
| 161 |
+
|
| 162 |
+
## English summary — Erk-32B
|
| 163 |
+
|
| 164 |
+
Erk-32B is Qwen3-32B continued-pretrained on 1.05B tokens of Turkish and
|
| 165 |
+
instruction-tuned on 423M tokens (373k cleaned examples), released as merged
|
| 166 |
+
weights at LoRA scale 0.75 with a default identity system prompt and GGUF
|
| 167 |
+
quantizations (Q8_0, Q4_K_M). Every reported number passed a contamination audit
|
| 168 |
+
(113/900 TurkishMMLU questions found verbatim in the training corpus and
|
| 169 |
+
excluded), option rotation, forced-choice measurement and paired bootstrap CIs.
|
| 170 |
+
On clean TurkishMMLU (652 items) the released merged weights score 71.01% vs
|
| 171 |
+
67.64% for the base (+3.37 [+0.61, +6.13]); on TurkMorfBench v2 generation with the system prompt
|
| 172 |
+
59.38% vs 31.64% (+27.73 [+22.46, +33.01]). On forced choice the gain over the
|
| 173 |
+
base is not demonstrable (+1.99 [−0.20, +4.18]); a +3.73 advantage reported
|
| 174 |
+
with the benchmark's first version was traced to 18 wrong gold answers and
|
| 175 |
+
withdrawn. Scale 0.40 scores 73.47% on TurkishMMLU (a borderline +1.99 over
|
| 176 |
+
0.75) but 10 points lower on generation with the system prompt; both rows are
|
| 177 |
+
in the report. Identity is
|
| 178 |
+
provided by a default system prompt in the chat template and states the base
|
| 179 |
+
model explicitly. Single training seed; generation quality, long context, code
|
| 180 |
+
and reasoning were not measured. Apache 2.0.
|
betikler/birlestir.py
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""LoRA'yi tabana BIRLESTIR: W = W_taban + OLCEK * (B @ A) * (alpha / r).
|
| 2 |
+
|
| 3 |
+
NEDEN: yayin icin tek parca model gerekiyor. LoRA + taban ikilisi calisma
|
| 4 |
+
noktasini kullaniciya birakir; birlesik model 0,80'i agirliga isler.
|
| 5 |
+
|
| 6 |
+
DOGRULAMA SART: birlestirme bf16'da yapilirsa (B@A) carpimi ve toplama ayri
|
| 7 |
+
ayri yuvarlanir; LoRA yolundaki x@A^T@B^T sirasindan farkli bir yuvarlama
|
| 8 |
+
olur. Fark kucuk ama sifir degil. Bu yuzden carpim fp32'de yapilir, sonuc
|
| 9 |
+
bf16'ya tek seferde yuvarlanir; ve birlesik model AYNI kiyas betigiyle
|
| 10 |
+
yeniden olculur (olcek 0,0 = "LoRA yok" = birlesik agirligin kendisi).
|
| 11 |
+
Beklenen: sohbet %69,00 / kiyas %71,01 (0,80 istemsiz satiri). Sapma
|
| 12 |
+
bootstrap gurultusunun disindaysa yayinlanmaz.
|
| 13 |
+
|
| 14 |
+
Cikti: safetensors + tokenizer, save_pretrained ile. LoRA anahtarlari
|
| 15 |
+
'model.layers.N.self_attn.q_proj.A' bicimindedir; taban agirligi
|
| 16 |
+
'model.layers.N.self_attn.q_proj.weight'. Eslesmeyen anahtar HATA'dir,
|
| 17 |
+
sessizce atlanmaz.
|
| 18 |
+
"""
|
| 19 |
+
import os, sys, json, time, torch
|
| 20 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 21 |
+
|
| 22 |
+
MID = "/ari/users/ytanis/qwen3-32b"
|
| 23 |
+
CK = os.environ.get("CK_DIR", "/ari/users/ytanis/erk32b-sft2")
|
| 24 |
+
OLCEK = float(os.environ.get("OLCEK", "0.80"))
|
| 25 |
+
CIKTI = os.environ.get("CIKTI", "/ari/users/ytanis/erk32b-birlesik-080")
|
| 26 |
+
R, ALPHA = 256, 512
|
| 27 |
+
S = ALPHA / R
|
| 28 |
+
|
| 29 |
+
t0 = time.time()
|
| 30 |
+
print("taban yukleniyor (CPU, bf16)...", flush=True)
|
| 31 |
+
model = AutoModelForCausalLM.from_pretrained(MID, torch_dtype=torch.bfloat16, device_map="cpu")
|
| 32 |
+
tok = AutoTokenizer.from_pretrained(MID)
|
| 33 |
+
sd = model.state_dict()
|
| 34 |
+
|
| 35 |
+
lsd = torch.load("%s/lora_ck.pt" % CK, map_location="cpu", weights_only=True)
|
| 36 |
+
print("LoRA tensor: %d | olcek %.2f | %.0f sn" % (len(lsd), OLCEK, time.time() - t0), flush=True)
|
| 37 |
+
|
| 38 |
+
# A ve B'yi modul basina esle
|
| 39 |
+
modul = {}
|
| 40 |
+
for k, v in lsd.items():
|
| 41 |
+
if k.endswith(".A") or k.endswith(".B"):
|
| 42 |
+
modul.setdefault(k[:-2], {})[k[-1]] = v
|
| 43 |
+
else:
|
| 44 |
+
raise SystemExit("beklenmeyen LoRA anahtari: %s" % k)
|
| 45 |
+
|
| 46 |
+
birlesen = 0; norm_top = 0.0
|
| 47 |
+
for ad, ab in modul.items():
|
| 48 |
+
if "A" not in ab or "B" not in ab:
|
| 49 |
+
raise SystemExit("eksik A/B: %s" % ad)
|
| 50 |
+
hedef = ad + ".weight"
|
| 51 |
+
if hedef not in sd:
|
| 52 |
+
raise SystemExit("taban agirligi bulunamadi: %s" % hedef)
|
| 53 |
+
A = ab["A"].float(); B = ab["B"].float() # fp32'de carp
|
| 54 |
+
delta = (B @ A) * (S * OLCEK)
|
| 55 |
+
if delta.shape != sd[hedef].shape:
|
| 56 |
+
raise SystemExit("sekil uyusmuyor %s: %s vs %s" % (hedef, tuple(delta.shape), tuple(sd[hedef].shape)))
|
| 57 |
+
yeni = (sd[hedef].float() + delta).to(torch.bfloat16) # tek yuvarlama
|
| 58 |
+
with torch.no_grad():
|
| 59 |
+
sd[hedef].copy_(yeni)
|
| 60 |
+
norm_top += delta.norm().item(); birlesen += 1
|
| 61 |
+
if birlesen % 100 == 0:
|
| 62 |
+
print(" %d/%d modul | %.0f sn" % (birlesen, len(modul), time.time() - t0), flush=True)
|
| 63 |
+
|
| 64 |
+
print("birlesen modul: %d | toplam delta normu: %.2f" % (birlesen, norm_top), flush=True)
|
| 65 |
+
if birlesen != len(modul) or birlesen == 0:
|
| 66 |
+
raise SystemExit("birlestirme eksik")
|
| 67 |
+
|
| 68 |
+
os.makedirs(CIKTI, exist_ok=True)
|
| 69 |
+
model.save_pretrained(CIKTI, safe_serialization=True, max_shard_size="5GB")
|
| 70 |
+
tok.save_pretrained(CIKTI)
|
| 71 |
+
json.dump({"taban": MID, "lora": CK, "olcek": OLCEK, "r": R, "alpha": ALPHA,
|
| 72 |
+
"birlesen_modul": birlesen, "delta_norm_toplam": norm_top,
|
| 73 |
+
"not": "carpim fp32, tek bf16 yuvarlama; kiyas dogrulamasi ayri betikte"},
|
| 74 |
+
open(os.path.join(CIKTI, "birlestirme.json"), "w"), indent=1)
|
| 75 |
+
print("KAYDEDILDI -> %s | %.0f sn" % (CIKTI, time.time() - t0), flush=True)
|
betikler/bootstrap_birlesik.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Birlesik model (olcek 0,0 = agirlikta 0,80) vs LoRA yolu (0,80): ayni soru vektorleri, esli."""
|
| 2 |
+
import json, numpy as np
|
| 3 |
+
A = json.load(open("/ari/users/ytanis/olcek_ince_sft2.json"))["0.80"]
|
| 4 |
+
B = json.load(open("/ari/users/ytanis/olcek_birlesik_080.json"))["0.00"]
|
| 5 |
+
rng = np.random.default_rng(0); N = 10000
|
| 6 |
+
for ad, k in (("SOHBET", "sohbet_vec"), ("KIYAS", "mmlu_vec")):
|
| 7 |
+
x = np.asarray(B[k], float); y = np.asarray(A[k], float); n = len(x)
|
| 8 |
+
ayni = int((x == y).sum())
|
| 9 |
+
idx = rng.integers(0, n, size=(N, n)); d = (x[idx].mean(1) - y[idx].mean(1)) * 100
|
| 10 |
+
lo, hi = np.percentile(d, [2.5, 97.5])
|
| 11 |
+
print(" %-7s birlesik vs LoRA: %+5.2f [%+5.2f, %+5.2f] ayni cevap %d/%d %s"
|
| 12 |
+
% (ad, (x.mean()-y.mean())*100, lo, hi, ayni, n, "ANLAMLI" if (lo > 0 or hi < 0) else "gurultu"))
|
betikler/bootstrap_ince.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""0,75-0,80 sohbet tepesi gercek mi? Kaba ve ince taramayi birlestirip esli bootstrap."""
|
| 2 |
+
import json, numpy as np
|
| 3 |
+
A = json.load(open("/ari/users/ytanis/olcek_ince_sft2.json"))
|
| 4 |
+
A.update(json.load(open("/ari/users/ytanis/olcek_ince_sft2_ince.json")))
|
| 5 |
+
rng = np.random.default_rng(0); N = 10000
|
| 6 |
+
def satir(ad, x, y):
|
| 7 |
+
x = np.asarray(x, float); y = np.asarray(y, float); n = len(x)
|
| 8 |
+
idx = rng.integers(0, n, size=(N, n)); d = (x[idx].mean(1) - y[idx].mean(1)) * 100
|
| 9 |
+
lo, hi = np.percentile(d, [2.5, 97.5])
|
| 10 |
+
print(" %-30s %+6.2f [%+6.2f, %+6.2f] %s" % (ad, (x.mean()-y.mean())*100, lo, hi, "ANLAMLI" if (lo > 0 or hi < 0) else "-"))
|
| 11 |
+
print("SOHBET (n=329, esli)")
|
| 12 |
+
for a, b in [("0.75","0.00"),("0.80","0.00"),("0.85","0.00"),("0.75","0.40"),("0.80","0.85"),("0.80","0.75"),("1.00","0.00")]:
|
| 13 |
+
satir("%s vs %s" % (a, b), A[a]["sohbet_vec"], A[b]["sohbet_vec"])
|
| 14 |
+
print("KIYAS (n=652, esli)")
|
| 15 |
+
for a, b in [("0.40","0.75"),("0.40","0.80"),("0.75","0.00"),("0.80","1.00")]:
|
| 16 |
+
satir("%s vs %s" % (a, b), A[a]["mmlu_vec"], A[b]["mmlu_vec"])
|
betikler/bootstrap_sft2.py
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Ek tur sonrasi olcek taramasi — esli bootstrap guven araliklari.
|
| 2 |
+
|
| 3 |
+
Soru-bazli vektorler ayni sorular uzerinde oldugu icin fark ESLI hesaplanir:
|
| 4 |
+
her yeniden orneklemede ayni soru indeksleri iki kosula da uygulanir. Bagimsiz
|
| 5 |
+
bootstrap'a gore araliklar daha dar ve dogru olur (soru zorlugu ortak varyans).
|
| 6 |
+
10.000 yeniden ornekleme, tohum 0 — OLCUM-PROTOKOLU ile ayni.
|
| 7 |
+
"""
|
| 8 |
+
import json, numpy as np
|
| 9 |
+
|
| 10 |
+
A = json.load(open("/ari/users/ytanis/olcek_ince_sft2.json")) # ek tur SONRASI
|
| 11 |
+
try:
|
| 12 |
+
B = json.load(open("/ari/users/ytanis/olcek_ince.json")) # ek tur ONCESI
|
| 13 |
+
except Exception:
|
| 14 |
+
B = {}
|
| 15 |
+
rng = np.random.default_rng(0)
|
| 16 |
+
N = 10000
|
| 17 |
+
|
| 18 |
+
def ci(x, y):
|
| 19 |
+
x = np.asarray(x, float); y = np.asarray(y, float); n = len(x)
|
| 20 |
+
assert n == len(y)
|
| 21 |
+
idx = rng.integers(0, n, size=(N, n))
|
| 22 |
+
d = (x[idx].mean(1) - y[idx].mean(1)) * 100
|
| 23 |
+
lo, hi = np.percentile(d, [2.5, 97.5])
|
| 24 |
+
return (x.mean() - y.mean()) * 100, lo, hi
|
| 25 |
+
|
| 26 |
+
def satir(ad, x, y):
|
| 27 |
+
f, lo, hi = ci(x, y)
|
| 28 |
+
anl = "ANLAMLI" if (lo > 0 or hi < 0) else " - "
|
| 29 |
+
print(" %-40s %+6.2f [%+6.2f, %+6.2f] %s" % (ad, f, lo, hi, anl))
|
| 30 |
+
|
| 31 |
+
print("EK TUR SONRASI — olcekler arasi (esli, n_sohbet=329, n_kiyas=652)")
|
| 32 |
+
print(" SOHBET")
|
| 33 |
+
for a, b in [("0.80", "0.00"), ("1.00", "0.00"), ("0.40", "0.00"), ("0.80", "0.40"), ("0.80", "1.00")]:
|
| 34 |
+
satir("sohbet %s vs %s" % (a, b), A[a]["sohbet_vec"], A[b]["sohbet_vec"])
|
| 35 |
+
print(" KIYAS")
|
| 36 |
+
for a, b in [("0.40", "0.00"), ("0.80", "0.00"), ("1.00", "0.00"), ("0.40", "0.80"), ("0.40", "1.00")]:
|
| 37 |
+
satir("kiyas %s vs %s" % (a, b), A[a]["mmlu_vec"], A[b]["mmlu_vec"])
|
| 38 |
+
|
| 39 |
+
if B:
|
| 40 |
+
print("\nEK TUR SONRASI vs ONCESI — ayni olcekte (esli)")
|
| 41 |
+
for o in ["0.40", "0.50", "1.00"]:
|
| 42 |
+
if o in B:
|
| 43 |
+
satir("sohbet %s: sonra vs once" % o, A[o]["sohbet_vec"], B[o]["sohbet_vec"])
|
| 44 |
+
satir("kiyas %s: sonra vs once" % o, A[o]["mmlu_vec"], B[o]["mmlu_vec"])
|
| 45 |
+
else:
|
| 46 |
+
print(" (%s once dosyasinda yok)" % o)
|
betikler/bootstrap_sistem.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json, numpy as np
|
| 2 |
+
A = json.load(open("/ari/users/ytanis/olcek_ince_sft2.json"))
|
| 3 |
+
S = json.load(open("/ari/users/ytanis/olcek_sistem_080.json"))["0.80"]
|
| 4 |
+
rng = np.random.default_rng(0); N = 10000
|
| 5 |
+
def satir(ad, x, y):
|
| 6 |
+
x = np.asarray(x, float); y = np.asarray(y, float); n = len(x)
|
| 7 |
+
idx = rng.integers(0, n, size=(N, n)); d = (x[idx].mean(1) - y[idx].mean(1)) * 100
|
| 8 |
+
lo, hi = np.percentile(d, [2.5, 97.5])
|
| 9 |
+
print(" %-34s %+6.2f [%+6.2f, %+6.2f] %s" % (ad, (x.mean()-y.mean())*100, lo, hi, "ANLAMLI" if (lo > 0 or hi < 0) else "-"))
|
| 10 |
+
print("SOHBET (n=329, esli)")
|
| 11 |
+
satir("0.80+sistem vs taban", S["sohbet_vec"], A["0.00"]["sohbet_vec"])
|
| 12 |
+
satir("0.80+sistem vs 0.80 istemsiz", S["sohbet_vec"], A["0.80"]["sohbet_vec"])
|
| 13 |
+
satir("0.80+sistem vs 0.40 istemsiz", S["sohbet_vec"], A["0.40"]["sohbet_vec"])
|
| 14 |
+
print("KIYAS (n=652, esli)")
|
| 15 |
+
satir("0.80+sistem vs taban", S["mmlu_vec"], A["0.00"]["mmlu_vec"])
|
betikler/cpt32b_train.py
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Erk-32B CPT — FSDP LoRA (r=256, tum lineer), checkpoint'li/kaldigi-yerden-devam.
|
| 2 |
+
Veri: tok_train.txt (~1B token) x2 epoch. Probe: TurkishMMLU DEV (test'e hic bakilmaz).
|
| 3 |
+
Kullanim: torchrun --nproc_per_node=4 cpt32b_train.py <sure_dk>
|
| 4 |
+
"""
|
| 5 |
+
import os, sys, time, math, json, glob, functools, torch, torch.nn as nn, torch.distributed as dist
|
| 6 |
+
from torch.distributed.fsdp import FullyShardedDataParallel as FSDP, MixedPrecision, StateDictType
|
| 7 |
+
from torch.distributed.fsdp.wrap import transformer_auto_wrap_policy
|
| 8 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 9 |
+
from transformers.models.qwen3.modeling_qwen3 import Qwen3DecoderLayer
|
| 10 |
+
os.environ["HF_DATASETS_OFFLINE"]="1"
|
| 11 |
+
|
| 12 |
+
dist.init_process_group("nccl")
|
| 13 |
+
rank=dist.get_rank(); local=int(os.environ["LOCAL_RANK"]); W=dist.get_world_size()
|
| 14 |
+
torch.cuda.set_device(local)
|
| 15 |
+
MID="/ari/users/ytanis/qwen3-32b"; OUT="/ari/users/ytanis/erk32b-cpt"
|
| 16 |
+
SEQ=2048; BS=4; R=256; ALPHA=512; LR=1e-4; WARMUP=200
|
| 17 |
+
# Tam program korunuyor. Kisaltma dusunuldu ve reddedildi: gerekce dev-150
|
| 18 |
+
# probe'unun 73-78 bandinda salinmasiydi, ancak 150 soruda %95 belirsizlik
|
| 19 |
+
# ±7 puan — bu salinim yavas ve gercek bir tirmanisla da uyumlu. Doyum
|
| 20 |
+
# kaniti yok. Karar bunun yerine OLCUME baglandi: her parca sonunda
|
| 21 |
+
# held-out 750 (bkz. eval32b_heldout.py, parca basina <200 cekirdek-saat,
|
| 22 |
+
# parca maliyetinin ~%3'u). Ust uste iki olcum guven araligi icinde kalirsa
|
| 23 |
+
# program orada kesilir.
|
| 24 |
+
TOTAL_TOKENS=2_100_000_000
|
| 25 |
+
STEP_TOKENS=SEQ*BS*W
|
| 26 |
+
TOTAL_STEPS=TOTAL_TOKENS//STEP_TOKENS
|
| 27 |
+
BUDGET_MIN=float(sys.argv[1]) if len(sys.argv)>1 else 1380 # 23 saat varsayilan
|
| 28 |
+
PROBE_EVERY=2000; SAVE_EVERY=500
|
| 29 |
+
if BUDGET_MIN<20: PROBE_EVERY=40; SAVE_EVERY=60 # duman: tum gecis yollarini dene
|
| 30 |
+
os.makedirs(OUT, exist_ok=True)
|
| 31 |
+
|
| 32 |
+
tok=AutoTokenizer.from_pretrained(MID)
|
| 33 |
+
model=AutoModelForCausalLM.from_pretrained(MID, torch_dtype=torch.bfloat16)
|
| 34 |
+
model.gradient_checkpointing_enable(gradient_checkpointing_kwargs={"use_reentrant":False})
|
| 35 |
+
model.enable_input_require_grads()
|
| 36 |
+
for p in model.parameters(): p.requires_grad=False
|
| 37 |
+
|
| 38 |
+
class LoRA(nn.Module):
|
| 39 |
+
def __init__(self, base, r=R, alpha=ALPHA):
|
| 40 |
+
super().__init__(); self.base=base
|
| 41 |
+
self.A=nn.Parameter(torch.zeros(r, base.in_features, dtype=torch.bfloat16))
|
| 42 |
+
self.B=nn.Parameter(torch.zeros(base.out_features, r, dtype=torch.bfloat16))
|
| 43 |
+
nn.init.kaiming_uniform_(self.A, a=math.sqrt(5)); self.s=alpha/r
|
| 44 |
+
def forward(self,x):
|
| 45 |
+
return self.base(x)+((x@self.A.t())@self.B.t())*self.s
|
| 46 |
+
|
| 47 |
+
for layer in model.model.layers:
|
| 48 |
+
for mod,names in ((layer.self_attn,["q_proj","k_proj","v_proj","o_proj"]),
|
| 49 |
+
(layer.mlp,["gate_proj","up_proj","down_proj"])):
|
| 50 |
+
for nm in names: setattr(mod,nm,LoRA(getattr(mod,nm)))
|
| 51 |
+
|
| 52 |
+
# --- durum: LoRA-only checkpoint (taban donuk; FSDP state-dict labirenti YOK) ---
|
| 53 |
+
state={"step":0,"tokens":0,"best_dev":0.0}
|
| 54 |
+
sf=f"{OUT}/state.json"; LCK=f"{OUT}/lora_ck.pt"
|
| 55 |
+
RESUME_AT=0
|
| 56 |
+
if os.path.exists(sf) and os.path.exists(LCK):
|
| 57 |
+
state=json.load(open(sf)); RESUME_AT=state["step"]
|
| 58 |
+
lsd=torch.load(LCK, map_location="cpu", weights_only=True) # saf tensor sozlugu
|
| 59 |
+
named=dict(model.named_parameters())
|
| 60 |
+
n=0
|
| 61 |
+
for k,v in lsd.items():
|
| 62 |
+
if k in named:
|
| 63 |
+
with torch.no_grad(): named[k].copy_(v)
|
| 64 |
+
n+=1
|
| 65 |
+
if rank==0: print(f"DEVAM: adim {state['step']} ({state['tokens']/1e9:.2f}B token) — {n} LoRA tensoru yuklendi", flush=True)
|
| 66 |
+
|
| 67 |
+
policy=functools.partial(transformer_auto_wrap_policy, transformer_layer_cls={Qwen3DecoderLayer})
|
| 68 |
+
model=FSDP(model, auto_wrap_policy=policy, device_id=local,
|
| 69 |
+
mixed_precision=MixedPrecision(param_dtype=torch.bfloat16, reduce_dtype=torch.bfloat16),
|
| 70 |
+
use_orig_params=True)
|
| 71 |
+
params=[p for p in model.parameters() if p.requires_grad]
|
| 72 |
+
opt=torch.optim.AdamW(params, lr=LR, betas=(0.9,0.95), weight_decay=0.01)
|
| 73 |
+
|
| 74 |
+
from torch.distributed.fsdp import FullStateDictConfig
|
| 75 |
+
_fcfg=FullStateDictConfig(offload_to_cpu=True, rank0_only=True)
|
| 76 |
+
def save_ck():
|
| 77 |
+
with FSDP.state_dict_type(model, StateDictType.FULL_STATE_DICT, _fcfg):
|
| 78 |
+
sd=model.state_dict()
|
| 79 |
+
if rank==0:
|
| 80 |
+
lora={k:v for k,v in sd.items() if k.endswith(".A") or k.endswith(".B")}
|
| 81 |
+
torch.save(lora, LCK+".tmp")
|
| 82 |
+
# Uzerine yazmadan ONCE bir oncekini sakla. Tek dosyaya yazmak, kotu
|
| 83 |
+
# giden bir kosuda geri donulecek nokta birakmiyor (olculdu: LR sonum
|
| 84 |
+
# kosusu adim 30.000 checkpoint'ini yok etti, geri donus imkansizlasti).
|
| 85 |
+
if os.path.exists(LCK):
|
| 86 |
+
os.replace(LCK, LCK+".onceki")
|
| 87 |
+
if os.path.exists(sf): os.replace(sf, sf+".onceki")
|
| 88 |
+
os.replace(LCK+".tmp", LCK)
|
| 89 |
+
json.dump(state, open(sf,"w"))
|
| 90 |
+
del sd; dist.barrier()
|
| 91 |
+
|
| 92 |
+
# SONUM KIPI: ANNEAL_STEPS>0 ise program burada bitirilir; LR, devam
|
| 93 |
+
# noktasindaki degerinden ANNEAL_STEPS adimda kosinusle SIFIRA iner.
|
| 94 |
+
# Gerekce: uzun program doyuma ulasti (adim 23.500/27.297/30.000 olcumleri
|
| 95 |
+
# istatistiksel olarak ayni), ancak LR hic sonumlenmedi. Sonum kazanci
|
| 96 |
+
# ucuza sinanir; getirmezse adim 30.000 checkpoint'i kullanilir.
|
| 97 |
+
ANNEAL=int(os.environ.get("ANNEAL_STEPS","0"))
|
| 98 |
+
def _kosinus(s):
|
| 99 |
+
pr=min(1.0,(s-WARMUP)/max(TOTAL_STEPS-WARMUP,1))
|
| 100 |
+
return LR*(0.1+0.45*(1+math.cos(math.pi*pr)))
|
| 101 |
+
LR0_ANNEAL=_kosinus(RESUME_AT) if ANNEAL else 0.0
|
| 102 |
+
if ANNEAL: TOTAL_STEPS=RESUME_AT+ANNEAL
|
| 103 |
+
|
| 104 |
+
def lr_at(s):
|
| 105 |
+
if ANNEAL:
|
| 106 |
+
pr=min(1.0,(s-RESUME_AT)/max(ANNEAL,1))
|
| 107 |
+
return LR0_ANNEAL*0.5*(1+math.cos(math.pi*pr))
|
| 108 |
+
if s<WARMUP: base=LR*(s+1)/WARMUP
|
| 109 |
+
else: base=_kosinus(s)
|
| 110 |
+
if RESUME_AT>0 and s-RESUME_AT<50: # parca gecisi: momentler sifir, kisa rampa
|
| 111 |
+
base*=max(0.1,(s-RESUME_AT+1)/50)
|
| 112 |
+
return base
|
| 113 |
+
|
| 114 |
+
# --- veri: hazir token onbellegi (pretokenize.py uretir; is icinde tokenizasyon YOK) ---
|
| 115 |
+
CACHE=f"{OUT}/tokens.pt"
|
| 116 |
+
assert os.path.exists(CACHE), "tokens.pt yok - once pretokenize.py kos"
|
| 117 |
+
ids_all=torch.load(CACHE, map_location="cpu")
|
| 118 |
+
N=len(ids_all)
|
| 119 |
+
if rank==0: print(f"korpus: {N/1e9:.2f}B token | hedef {TOTAL_TOKENS/1e9:.1f}B ({TOTAL_STEPS} adim) | bu parca {BUDGET_MIN:.0f} dk", flush=True)
|
| 120 |
+
|
| 121 |
+
# --- probe: TurkishMMLU test'ten SABIT 150 soru (faz14 formulu) ---
|
| 122 |
+
# Final rapor BU SORULAR HARIC held-out 750 uzerinde verilir (secim sizintisi yok).
|
| 123 |
+
# FSDP notu: her forward kolektiftir -> TUM ranklar AYNI sorulari ayni sirayla isler
|
| 124 |
+
# (rank-bazli bolme farkli forward sayisi yaratir ve NCCL kilitlenmesine yol acar).
|
| 125 |
+
from datasets import load_dataset
|
| 126 |
+
_full=load_dataset("AYueksel/TurkishMMLU","All",split="test")
|
| 127 |
+
_pidx=list(range(1,len(_full),6))[:150]
|
| 128 |
+
dev=_full.select(_pidx)
|
| 129 |
+
letters="ABCDE"; lid=[tok(" "+c, add_special_tokens=False).input_ids[-1] for c in letters]
|
| 130 |
+
def dev_probe():
|
| 131 |
+
model.eval(); cor=0; tot=0
|
| 132 |
+
with torch.no_grad():
|
| 133 |
+
for i in range(len(dev)):
|
| 134 |
+
ex=dev[i]
|
| 135 |
+
a=ex["answer"]; ans=int(a) if isinstance(a,int) else (letters.index(str(a).strip()) if str(a).strip() in letters else int(a))
|
| 136 |
+
ch=list(ex["choices"]); s="Asagidaki coktan secmeli soruyu cevapla.\n\nSoru: "+str(ex["question"])+"\n"
|
| 137 |
+
for j,c in enumerate(ch[:5]): s+=f"{letters[j]}) {c}\n"
|
| 138 |
+
ids=tok(s+"Cevap:", return_tensors="pt", truncation=True, max_length=1024).input_ids.to(local)
|
| 139 |
+
lg=model(ids).logits[0,-1]
|
| 140 |
+
cor+=int(int(torch.stack([lg[t] for t in lid]).argmax())==ans); tot+=1
|
| 141 |
+
model.train()
|
| 142 |
+
return 100*cor/max(tot,1)
|
| 143 |
+
|
| 144 |
+
t_start=time.time(); t_last=t_start; run=0.0; nacc=0
|
| 145 |
+
model.train()
|
| 146 |
+
# NOT: adim-0 probe bilerek YOK — FSDP yurutme-sirasi ilk forward'da kurulur; ilk forward
|
| 147 |
+
# eval olursa egitime geciste kilitlenir (olculdu). Stok dev-150 referansi: %68.7 (is 511041).
|
| 148 |
+
while state["step"]<TOTAL_STEPS:
|
| 149 |
+
s=state["step"]
|
| 150 |
+
xs=[]
|
| 151 |
+
for b in range(BS):
|
| 152 |
+
a=((s*W+rank)*BS+b)*SEQ % (N-SEQ-1)
|
| 153 |
+
xs.append(ids_all[a:a+SEQ].to(torch.long))
|
| 154 |
+
ids=torch.stack(xs).to(local)
|
| 155 |
+
out=model(input_ids=ids, labels=ids)
|
| 156 |
+
out.loss.backward()
|
| 157 |
+
for g in opt.param_groups: g["lr"]=lr_at(s)
|
| 158 |
+
model.clip_grad_norm_(1.0)
|
| 159 |
+
opt.step(); opt.zero_grad()
|
| 160 |
+
run+=out.loss.item(); nacc+=1; state["step"]+=1; state["tokens"]+=STEP_TOKENS
|
| 161 |
+
if state["step"]%100==0 and rank==0:
|
| 162 |
+
# nacc ile bol, 100 ile degil: devam sonrasi ilk satirda yalnizca
|
| 163 |
+
# birkac adim birikmis olur ve sabit 100 bolmesi kaybi ~30 kat dusuk,
|
| 164 |
+
# tok/s'yi ~30 kat yuksek gosterip sahte alarm uretir.
|
| 165 |
+
el=(time.time()-t_start)/60
|
| 166 |
+
tps=STEP_TOKENS*nacc/max(time.time()-t_last,1e-9); t_last=time.time()
|
| 167 |
+
print(f"adim {state['step']}/{TOTAL_STEPS} kayip {run/max(nacc,1):.4f} lr {lr_at(s):.2e} {tps:.0f}tok/s {el:.0f}dk", flush=True)
|
| 168 |
+
run=0.0; nacc=0
|
| 169 |
+
if state["step"]%SAVE_EVERY==0:
|
| 170 |
+
save_ck()
|
| 171 |
+
if state["step"]%PROBE_EVERY==0:
|
| 172 |
+
p=dev_probe()
|
| 173 |
+
if rank==0:
|
| 174 |
+
print(f" PROBE adim {state['step']}: DEV %{p:.1f} ({state['tokens']/1e9:.2f}B token)", flush=True)
|
| 175 |
+
if p>state["best_dev"]: state["best_dev"]=p
|
| 176 |
+
# SURE KONTROLU KOLEKTIF: yerel saat farklari rank'lari farkli adimda durdurup
|
| 177 |
+
# NCCL kilidine yol acar (olculdu, is 511050) — karar all-reduce ile ortaklanir.
|
| 178 |
+
_stop=torch.tensor([1.0 if (time.time()-t_start)/60>BUDGET_MIN else 0.0], device=local)
|
| 179 |
+
dist.all_reduce(_stop, op=dist.ReduceOp.MAX)
|
| 180 |
+
if _stop.item()>0:
|
| 181 |
+
if rank==0: print(f"SURE DOLDU ({BUDGET_MIN:.0f}dk) — checkpoint alinip cikiliyor", flush=True)
|
| 182 |
+
break
|
| 183 |
+
save_ck()
|
| 184 |
+
if rank==0: print(f"PARCA BITTI: adim {state['step']}/{TOTAL_STEPS} ({state['tokens']/1e9:.2f}B token)", flush=True)
|
| 185 |
+
dist.destroy_process_group()
|
betikler/ek_sft_sinav.py
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Ek SFT turunun sinavi: kimlik + hata bulma + gerileme kontrolu.
|
| 2 |
+
|
| 3 |
+
UC SORU
|
| 4 |
+
1) KIMLIK: model kendini dogru tanitiyor mu? Onceden tabanin sahibini
|
| 5 |
+
("Tongyi/Alibaba") soyluyordu.
|
| 6 |
+
2) HATA BULMA: serbest metinde morfolojik hatayi bulabiliyor mu?
|
| 7 |
+
Nitel denemede "Kitapı masaya koydum" cumlesini DOGRU bulmustu.
|
| 8 |
+
SINAV GOVDELERI EGITIMDE HIC KULLANILMADI — egitim verisi uretilirken
|
| 9 |
+
kiyasin 29 govdesi bilincli olarak disarida birakilmisti. Temiz sinav.
|
| 10 |
+
3) GERILEME: iki dar gorev ogretirken genel yetenek bozuldu mu?
|
| 11 |
+
(kiyas puani ayri betikte olculur)
|
| 12 |
+
|
| 13 |
+
Karsilastirma: ek tur ONCESI (erk32b-sft) ve SONRASI (erk32b-sft2).
|
| 14 |
+
"""
|
| 15 |
+
import os, sys, json, re, gc, torch, torch.nn as nn
|
| 16 |
+
os.environ["HF_DATASETS_OFFLINE"] = "1"
|
| 17 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 18 |
+
|
| 19 |
+
MID = "/ari/users/ytanis/qwen3-32b"
|
| 20 |
+
ONCE = "/ari/users/ytanis/erk32b-sft"
|
| 21 |
+
SONRA = "/ari/users/ytanis/erk32b-sft2"
|
| 22 |
+
OUT = "/ari/users/ytanis/ek_sft_sinav.json"
|
| 23 |
+
R, ALPHA, OLCEK = 256, 512, 0.40
|
| 24 |
+
|
| 25 |
+
# --- KIMLIK sinavi
|
| 26 |
+
KIMLIK = [
|
| 27 |
+
("Seni kim geliştirdi?", ["eCloud"], ["Tongyi", "Alibaba", "OpenAI"]),
|
| 28 |
+
("Kimsin?", ["Erk"], ["Tongyi", "Alibaba"]),
|
| 29 |
+
("Sen Qwen misin?", ["eCloud", "Erk"], []),
|
| 30 |
+
("Temel modelin ne?", ["Qwen"], []), # tabani SOYLEMELI
|
| 31 |
+
("Hangi şirket seni yaptı?", ["eCloud"], ["Tongyi", "Alibaba"]),
|
| 32 |
+
]
|
| 33 |
+
|
| 34 |
+
# --- HATA BULMA sinavi: govdeler egitimde YOK (kiyasin yasakli listesi)
|
| 35 |
+
# (cumle, hatali_mi, dogru_bicim)
|
| 36 |
+
HATA = [
|
| 37 |
+
("Kitapı masaya koydum.", True, "kitabı"),
|
| 38 |
+
("Kitabı masaya koydum.", False, None),
|
| 39 |
+
("Ağaça baktım.", True, "ağaca"),
|
| 40 |
+
("Ağaca baktım.", False, None),
|
| 41 |
+
("Çocukun oyuncağı kayboldu.", True, "çocuğun"),
|
| 42 |
+
("Çocuğun oyuncağı kayboldu.", False, None),
|
| 43 |
+
("Ekmekler taze.", False, None),
|
| 44 |
+
("Ekmeklar taze.", True, "ekmekler"),
|
| 45 |
+
("Okulda kimse yoktu.", False, None),
|
| 46 |
+
("Okulta kimse yoktu.", True, "okulda"),
|
| 47 |
+
("Gözlar yorgun.", True, "gözler"),
|
| 48 |
+
("Gözler yorgun.", False, None),
|
| 49 |
+
]
|
| 50 |
+
|
| 51 |
+
tok = AutoTokenizer.from_pretrained(MID)
|
| 52 |
+
model = AutoModelForCausalLM.from_pretrained(MID, torch_dtype=torch.bfloat16,
|
| 53 |
+
device_map="auto").eval()
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
class LoRA(nn.Module):
|
| 57 |
+
OLCEK = OLCEK
|
| 58 |
+
def __init__(self, base):
|
| 59 |
+
super().__init__(); self.base = base
|
| 60 |
+
d = base.weight.device
|
| 61 |
+
self.A = nn.Parameter(torch.zeros(R, base.in_features, device=d, dtype=torch.bfloat16))
|
| 62 |
+
self.B = nn.Parameter(torch.zeros(base.out_features, R, device=d, dtype=torch.bfloat16))
|
| 63 |
+
self.s = ALPHA / R
|
| 64 |
+
def forward(self, x):
|
| 65 |
+
if LoRA.OLCEK == 0.0:
|
| 66 |
+
return self.base(x)
|
| 67 |
+
return self.base(x) + ((x @ self.A.t()) @ self.B.t()) * (self.s * LoRA.OLCEK)
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
for layer in model.model.layers:
|
| 71 |
+
for mod, adlar in ((layer.self_attn, ["q_proj", "k_proj", "v_proj", "o_proj"]),
|
| 72 |
+
(layer.mlp, ["gate_proj", "up_proj", "down_proj"])):
|
| 73 |
+
for nm in adlar: setattr(mod, nm, LoRA(getattr(mod, nm)))
|
| 74 |
+
named = dict(model.named_parameters())
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
def yukle(dizin):
|
| 78 |
+
lsd = torch.load("%s/lora_ck.pt" % dizin, map_location="cpu", weights_only=True)
|
| 79 |
+
for k, v in lsd.items():
|
| 80 |
+
if k in named:
|
| 81 |
+
with torch.no_grad(): named[k].copy_(v.to(named[k].device))
|
| 82 |
+
del lsd; gc.collect(); model.eval()
|
| 83 |
+
return json.load(open("%s/state.json" % dizin))["step"]
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
def sor(istem, maks=400):
|
| 87 |
+
p = "<|im_start|>user\n%s /no_think<|im_end|>\n<|im_start|>assistant\n" % istem
|
| 88 |
+
ids = tok(p, return_tensors="pt", add_special_tokens=False).to(model.device)
|
| 89 |
+
with torch.no_grad():
|
| 90 |
+
o = model.generate(**ids, max_new_tokens=maks, do_sample=False,
|
| 91 |
+
pad_token_id=tok.eos_token_id)
|
| 92 |
+
r = tok.decode(o[0][ids.input_ids.shape[1]:], skip_special_tokens=True)
|
| 93 |
+
return r.split("</think>", 1)[1].strip() if "</think>" in r else r.strip()
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
def sinav(etiket):
|
| 97 |
+
print("\n" + "=" * 66, flush=True)
|
| 98 |
+
print(" %s" % etiket, flush=True)
|
| 99 |
+
print("=" * 66, flush=True)
|
| 100 |
+
|
| 101 |
+
# 1) kimlik
|
| 102 |
+
k_dogru = 0
|
| 103 |
+
print("\n-- KIMLIK", flush=True)
|
| 104 |
+
for soru, olmali, olmamali in KIMLIK:
|
| 105 |
+
c = sor(soru, 250)
|
| 106 |
+
iyi = (any(x.lower() in c.lower() for x in olmali) and
|
| 107 |
+
not any(x.lower() in c.lower() for x in olmamali))
|
| 108 |
+
k_dogru += iyi
|
| 109 |
+
print(" %s %-28s %s" % ("✓" if iyi else "✗", soru, c[:80].replace("\n", " ")), flush=True)
|
| 110 |
+
|
| 111 |
+
# 2) hata bulma
|
| 112 |
+
h_dogru = 0
|
| 113 |
+
print("\n-- HATA BULMA (govdeler egitimde YOK)", flush=True)
|
| 114 |
+
for cumle, hatali_mi, dogru in HATA:
|
| 115 |
+
c = sor('Şu cümlede yazım hatası var mı? Varsa düzelt:\n\n%s' % cumle, 300)
|
| 116 |
+
cl = c.lower()
|
| 117 |
+
hata_dedi = bool(re.search(r"hata var|yanlış|düzelt|olmalı|doğrusu", cl)) and \
|
| 118 |
+
not re.search(r"hata yok|doğru yazılmış|hata bulunmuyor", cl)
|
| 119 |
+
if hatali_mi:
|
| 120 |
+
iyi = hata_dedi and (dogru.lower() in cl)
|
| 121 |
+
else:
|
| 122 |
+
iyi = not hata_dedi
|
| 123 |
+
h_dogru += iyi
|
| 124 |
+
print(" %s %-32s -> %s" % ("✓" if iyi else "✗", cumle, c[:70].replace("\n", " ")), flush=True)
|
| 125 |
+
|
| 126 |
+
print("\n KIMLIK %d/%d" % (k_dogru, len(KIMLIK)), flush=True)
|
| 127 |
+
print(" HATA BULMA %d/%d" % (h_dogru, len(HATA)), flush=True)
|
| 128 |
+
return {"kimlik": k_dogru, "kimlik_n": len(KIMLIK),
|
| 129 |
+
"hata": h_dogru, "hata_n": len(HATA)}
|
| 130 |
+
|
| 131 |
+
|
| 132 |
+
son = {}
|
| 133 |
+
a = yukle(ONCE); son["once"] = sinav("EK TUR ONCESI (adim %d)" % a)
|
| 134 |
+
b = yukle(SONRA); son["sonra"] = sinav("EK TUR SONRASI (adim %d)" % b)
|
| 135 |
+
|
| 136 |
+
print("\n" + "=" * 66, flush=True)
|
| 137 |
+
print(" ONCE kimlik %d/%d · hata bulma %d/%d"
|
| 138 |
+
% (son["once"]["kimlik"], son["once"]["kimlik_n"],
|
| 139 |
+
son["once"]["hata"], son["once"]["hata_n"]), flush=True)
|
| 140 |
+
print(" SONRA kimlik %d/%d · hata bulma %d/%d"
|
| 141 |
+
% (son["sonra"]["kimlik"], son["sonra"]["kimlik_n"],
|
| 142 |
+
son["sonra"]["hata"], son["sonra"]["hata_n"]), flush=True)
|
| 143 |
+
json.dump(son, open(OUT, "w"), ensure_ascii=False)
|
| 144 |
+
print("BITTI", flush=True)
|
betikler/eval32b_heldout.py
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Erk-32B ara degerlendirme — HELD-OUT 750 (probe'un 150 sorusu HARIC).
|
| 2 |
+
Mevcut LoRA checkpoint'i taban modele takip gercek sayiyi olcer."""
|
| 3 |
+
import os, json, math, torch, torch.nn as nn
|
| 4 |
+
os.environ["HF_DATASETS_OFFLINE"]="1"
|
| 5 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 6 |
+
from datasets import load_dataset
|
| 7 |
+
|
| 8 |
+
MID="/ari/users/ytanis/qwen3-32b"
|
| 9 |
+
# Olculecek checkpoint dizini disaridan verilebilir (CPT / SFT ayni betikle
|
| 10 |
+
# ayni protokolde olculsun diye).
|
| 11 |
+
OUT=os.environ.get("CK_DIR", "/ari/users/ytanis/erk32b-cpt")
|
| 12 |
+
R=256; ALPHA=512
|
| 13 |
+
tok=AutoTokenizer.from_pretrained(MID)
|
| 14 |
+
model=AutoModelForCausalLM.from_pretrained(MID, torch_dtype=torch.bfloat16, device_map="auto").eval()
|
| 15 |
+
|
| 16 |
+
class LoRA(nn.Module):
|
| 17 |
+
def __init__(self, base, r=R, alpha=ALPHA):
|
| 18 |
+
super().__init__(); self.base=base
|
| 19 |
+
d=base.weight.device
|
| 20 |
+
self.A=nn.Parameter(torch.zeros(r, base.in_features, device=d, dtype=torch.bfloat16))
|
| 21 |
+
self.B=nn.Parameter(torch.zeros(base.out_features, r, device=d, dtype=torch.bfloat16))
|
| 22 |
+
self.s=alpha/r
|
| 23 |
+
def forward(self,x):
|
| 24 |
+
return self.base(x)+((x@self.A.t())@self.B.t())*self.s
|
| 25 |
+
for layer in model.model.layers:
|
| 26 |
+
for mod,names in ((layer.self_attn,["q_proj","k_proj","v_proj","o_proj"]),
|
| 27 |
+
(layer.mlp,["gate_proj","up_proj","down_proj"])):
|
| 28 |
+
for nm in names: setattr(mod,nm,LoRA(getattr(mod,nm)))
|
| 29 |
+
|
| 30 |
+
st=json.load(open(f"{OUT}/state.json"))
|
| 31 |
+
lsd=torch.load(f"{OUT}/lora_ck.pt", map_location="cpu", weights_only=True)
|
| 32 |
+
named=dict(model.named_parameters()); n=0
|
| 33 |
+
for k,v in lsd.items():
|
| 34 |
+
if k in named:
|
| 35 |
+
with torch.no_grad(): named[k].copy_(v.to(named[k].device))
|
| 36 |
+
n+=1
|
| 37 |
+
print(f"LoRA yuklendi: {n} tensor | adim {st['step']} ({st['tokens']/1e9:.2f}B token)", flush=True)
|
| 38 |
+
|
| 39 |
+
ds=load_dataset("AYueksel/TurkishMMLU","All",split="test")
|
| 40 |
+
letters="ABCDE"; lid=[tok(" "+c, add_special_tokens=False).input_ids[-1] for c in letters]
|
| 41 |
+
probe=set(list(range(1,len(ds),6))[:150])
|
| 42 |
+
held=[i for i in range(min(900,len(ds))) if i not in probe]
|
| 43 |
+
# --- Olcum protokolu (adim 23500'de sabitlendi, olculdu):
|
| 44 |
+
# 1) probe'un 150 sorusu haric -> secim sizintisi yok
|
| 45 |
+
# 2) kirli sorular haric -> kulliyatta 13-kelime birebir gecenler
|
| 46 |
+
# (held-out 750'nin 98'i; bkz. kirlilik_CPT.json)
|
| 47 |
+
# 3) sik sirasi dondurulur -> harf/konum onyargisi elenir
|
| 48 |
+
# Bu ucu birden uygulanmadan olculen fark ~2 puan sisiyor (6.27 -> 4.14).
|
| 49 |
+
KIR=set()
|
| 50 |
+
try:
|
| 51 |
+
KIR=set(json.load(open("/ari/users/ytanis/kirlilik_CPT.json"))["kirli_13"])
|
| 52 |
+
except Exception as e:
|
| 53 |
+
print("UYARI: kirlilik listesi okunamadi (%s) — temiz alt kume raporlanmayacak" % e, flush=True)
|
| 54 |
+
temiz=[i for i in held if i not in KIR]
|
| 55 |
+
|
| 56 |
+
def run(kaydir):
|
| 57 |
+
v=[]
|
| 58 |
+
with torch.no_grad():
|
| 59 |
+
for i in held:
|
| 60 |
+
ex=ds[i]
|
| 61 |
+
try:
|
| 62 |
+
a=ex["answer"]; ans=int(a) if isinstance(a,int) else letters.index(str(a).strip())
|
| 63 |
+
except: v.append(None); continue
|
| 64 |
+
ch=list(ex["choices"])[:5]; k=len(ch)
|
| 65 |
+
if kaydir:
|
| 66 |
+
ch=ch[-kaydir:]+ch[:-kaydir]; ans=(ans+kaydir)%k
|
| 67 |
+
s="Asagidaki coktan secmeli soruyu cevapla.\n\nSoru: "+str(ex["question"])+"\n"
|
| 68 |
+
for j,c in enumerate(ch): s+=f"{letters[j]}) {c}\n"
|
| 69 |
+
ids=tok(s+"Cevap:", return_tensors="pt", truncation=True, max_length=1024).input_ids.to(model.device)
|
| 70 |
+
lg=model(ids).logits[0,-1]
|
| 71 |
+
v.append(int(int(torch.stack([lg[t] for t in lid[:k]]).argmax())==ans))
|
| 72 |
+
return v
|
| 73 |
+
|
| 74 |
+
def oran(v, idx):
|
| 75 |
+
z=[v[held.index(i)] for i in idx if v[held.index(i)] is not None]
|
| 76 |
+
return 100*sum(z)/max(len(z),1), len(z)
|
| 77 |
+
|
| 78 |
+
sonuc={"step":st["step"],"tokens":st["tokens"]}
|
| 79 |
+
# Asama etiketi checkpoint dizininden turetilir; sabit "CPT" yazmak SFT
|
| 80 |
+
# olcumlerinde yaniltici log uretiyordu.
|
| 81 |
+
ASAMA = "SFT" if OUT.rstrip("/").endswith("sft") else "CPT"
|
| 82 |
+
print(f"\n=== ERK-32B ({ASAMA}, adim {st['step']}, {st['tokens']/1e9:.2f}B token) ===", flush=True)
|
| 83 |
+
for ad,kay in (("orijinal",0),("dondurulmus",1)):
|
| 84 |
+
v=run(kay); sonuc["vec_"+ad]=v
|
| 85 |
+
a750,n750=oran(v,held); atem,ntem=oran(v,temiz)
|
| 86 |
+
sonuc[ad]={"held750":a750,"temiz":atem,"n_temiz":ntem}
|
| 87 |
+
print(f" {ad:12s} held-out {n750}: %{a750:.2f} | TEMIZ {ntem}: %{atem:.2f}", flush=True)
|
| 88 |
+
print(f"\nRAPORLANACAK SAYI (temiz + dondurulmus): %{sonuc['dondurulmus']['temiz']:.2f}", flush=True)
|
| 89 |
+
print(f" stok Qwen3-32B ayni kosulda: %67.64 (adim 23500 olcumunden)", flush=True)
|
| 90 |
+
json.dump(sonuc, open(f"{OUT}/heldout_step{st['step']}.json","w"))
|
| 91 |
+
print("BITTI", flush=True)
|
betikler/gguf_uret.py
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Birlesik Erk-32B -> GGUF (BF16) -> Q8_0 ve Q4_K_M, ardindan dogrulama.
|
| 2 |
+
|
| 3 |
+
NEDEN DERLEME YOK: kume gcc 8.5 ile llama.cpp'yi baglayamadi, toolset-12 dizini
|
| 4 |
+
bos. Donusum saf Python (gguf-py), nicemleme hazir CPU tekerlegindeki
|
| 5 |
+
llama_cpp.llama_model_quantize ile yapiliyor. Surumler sabit: llama.cpp git
|
| 6 |
+
<llama_cpp_surum.txt>, llama-cpp-python 0.3.35.
|
| 7 |
+
|
| 8 |
+
DOGRULAMA — nicemleme yayinlanan modeli degistirir, o yuzden her nicem icin:
|
| 9 |
+
1) kimlik: 6 soru, sistem istemiyle (sablon icinde varsayilan) — 6/6 beklenir
|
| 10 |
+
2) NLL: Turkce metin parcalarinda ortalama negatif log-olasilik, BF16'ya gore
|
| 11 |
+
artis yuzdesi. Q8_0 icin ~%0-1, Q4_K_M icin birkac yuzde beklenir; buyuk
|
| 12 |
+
sapma nicemlemenin bozuk oldugunu gosterir ve yayinlanmaz.
|
| 13 |
+
Kiyas puani (TurkishMMLU) GGUF uzerinde OLCULMEZ — 32B'yi CPU'da 652 soru
|
| 14 |
+
kosturmak saatler surer; NLL ve kimlik ile yetinilir ve bu raporda yazilir.
|
| 15 |
+
"""
|
| 16 |
+
import os, sys, json, time, subprocess, math
|
| 17 |
+
|
| 18 |
+
KOK = "/ari/users/ytanis"
|
| 19 |
+
BIRLESIK = os.environ.get("BIRLESIK", KOK + "/erk32b-birlesik-080")
|
| 20 |
+
CIKTI = os.environ.get("GGUF_DIR", KOK + "/erk32b-gguf")
|
| 21 |
+
AD = os.environ.get("GGUF_AD", "Erk-32B")
|
| 22 |
+
PY_TORCH = KOK + "/envs/torch/bin/python"
|
| 23 |
+
PY_GGUF = KOK + "/envs/gguf/bin/python"
|
| 24 |
+
DONUSTUR = KOK + "/llama.cpp/convert_hf_to_gguf.py"
|
| 25 |
+
NLL_METIN = os.environ.get("NLL_METIN", KOK + "/erk/nll_ornek.txt") # 8 x ~400 kelime Turkce
|
| 26 |
+
os.makedirs(CIKTI, exist_ok=True)
|
| 27 |
+
bf16 = "%s/%s-BF16.gguf" % (CIKTI, AD)
|
| 28 |
+
q8 = "%s/%s-Q8_0.gguf" % (CIKTI, AD)
|
| 29 |
+
q4 = "%s/%s-Q4_K_M.gguf" % (CIKTI, AD)
|
| 30 |
+
t0 = time.time()
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def adim(ad):
|
| 34 |
+
print("\n=== %s | %.0f dk ===" % (ad, (time.time() - t0) / 60), flush=True)
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
# 1) donusum (torch ortami: gguf-py + transformers)
|
| 38 |
+
if not os.path.exists(bf16):
|
| 39 |
+
adim("BF16 GGUF donusumu")
|
| 40 |
+
subprocess.run([PY_TORCH, DONUSTUR, BIRLESIK, "--outfile", bf16, "--outtype", "bf16"], check=True)
|
| 41 |
+
print("BF16: %.1f GB" % (os.path.getsize(bf16) / 1e9), flush=True)
|
| 42 |
+
|
| 43 |
+
# 2) nicemleme (gguf ortami: hazir tekerlek)
|
| 44 |
+
NICEM = r'''
|
| 45 |
+
import sys, llama_cpp
|
| 46 |
+
src, dst, tur = sys.argv[1], sys.argv[2], sys.argv[3]
|
| 47 |
+
p = llama_cpp.llama_model_quantize_default_params()
|
| 48 |
+
p.ftype = getattr(llama_cpp, "LLAMA_FTYPE_MOSTLY_" + tur)
|
| 49 |
+
p.nthread = 16
|
| 50 |
+
r = llama_cpp.llama_model_quantize(src.encode(), dst.encode(), p)
|
| 51 |
+
print("quantize", tur, "donus kodu", r); sys.exit(r)
|
| 52 |
+
'''
|
| 53 |
+
for dst, tur in ((q8, "Q8_0"), (q4, "Q4_K_M")):
|
| 54 |
+
if not os.path.exists(dst):
|
| 55 |
+
adim("nicemleme " + tur)
|
| 56 |
+
subprocess.run([PY_GGUF, "-c", NICEM, bf16, dst, tur], check=True)
|
| 57 |
+
print("%s: %.1f GB" % (tur, os.path.getsize(dst) / 1e9), flush=True)
|
| 58 |
+
|
| 59 |
+
# 3) dogrulama
|
| 60 |
+
DOGRULA = r'''
|
| 61 |
+
import sys, json, math, llama_cpp
|
| 62 |
+
from llama_cpp import Llama
|
| 63 |
+
yol, metin_yolu = sys.argv[1], sys.argv[2]
|
| 64 |
+
llm = Llama(model_path=yol, n_ctx=1024, n_threads=16, logits_all=True, verbose=False)
|
| 65 |
+
# kimlik: sablon icindeki varsayilan sistem istemi devreye girmeli
|
| 66 |
+
sorular = ["Seni kim geliştirdi?", "Kimsin?", "Sen Qwen misin?", "Temel modelin ne?",
|
| 67 |
+
"Hangi şirket seni yaptı?", "Sen ChatGPT misin?"]
|
| 68 |
+
kimlik = 0; cevaplar = []
|
| 69 |
+
for s in sorular:
|
| 70 |
+
r = llm.create_chat_completion(messages=[{"role": "user", "content": s + " /no_think"}],
|
| 71 |
+
max_tokens=120, temperature=0)
|
| 72 |
+
c = r["choices"][0]["message"]["content"].split("</think>")[-1].strip()
|
| 73 |
+
cl = c.lower()
|
| 74 |
+
iyi = ("erk" in cl or "ecloud" in cl) and not any(x in cl for x in ("alibaba", "tongyi", "openai", "chatgpt"))
|
| 75 |
+
if s == "Temel modelin ne?": iyi = "qwen" in cl
|
| 76 |
+
kimlik += iyi; cevaplar.append((s, iyi, c[:80]))
|
| 77 |
+
# NLL: metin parcalari
|
| 78 |
+
parcalar = [p.strip() for p in open(metin_yolu, encoding="utf-8").read().split("\n\n") if len(p.split()) > 50][:8]
|
| 79 |
+
top_nll = 0.0; top_n = 0
|
| 80 |
+
for p in parcalar:
|
| 81 |
+
ids = llm.tokenize(p.encode("utf-8"))[:768]
|
| 82 |
+
llm.reset(); llm.eval(ids)
|
| 83 |
+
import numpy as np
|
| 84 |
+
lg = np.asarray(llm.scores[:len(ids)], dtype=np.float32) # [n, vocab]
|
| 85 |
+
for i in range(len(ids) - 1):
|
| 86 |
+
row = lg[i]; m = row.max(); lse = m + math.log(np.exp(row - m).sum())
|
| 87 |
+
top_nll += lse - row[ids[i + 1]]; top_n += 1
|
| 88 |
+
json.dump({"kimlik": kimlik, "n_kimlik": len(sorular), "cevaplar": cevaplar,
|
| 89 |
+
"nll": top_nll / max(top_n, 1), "token": top_n}, open(yol + ".dogrulama.json", "w"), ensure_ascii=False, indent=1)
|
| 90 |
+
print("%s | kimlik %d/%d | NLL %.4f (%d token)" % (yol.split("/")[-1], kimlik, len(sorular), top_nll / max(top_n, 1), top_n))
|
| 91 |
+
'''
|
| 92 |
+
son = {}
|
| 93 |
+
for yol in (bf16, q8, q4):
|
| 94 |
+
adim("dogrulama " + os.path.basename(yol))
|
| 95 |
+
subprocess.run([PY_GGUF, "-c", DOGRULA, yol, NLL_METIN], check=True)
|
| 96 |
+
son[os.path.basename(yol)] = json.load(open(yol + ".dogrulama.json"))
|
| 97 |
+
|
| 98 |
+
adim("OZET")
|
| 99 |
+
taban = son[os.path.basename(bf16)]["nll"]
|
| 100 |
+
for k, v in son.items():
|
| 101 |
+
print(" %-26s kimlik %d/%d NLL %.4f (BF16'ya gore %+.2f%%)"
|
| 102 |
+
% (k, v["kimlik"], v["n_kimlik"], v["nll"], 100 * (v["nll"] - taban) / taban), flush=True)
|
| 103 |
+
json.dump(son, open(CIKTI + "/dogrulama_ozet.json", "w"), ensure_ascii=False, indent=1)
|
| 104 |
+
print("BITTI", flush=True)
|
betikler/hata_duzeltme_uret.py
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Turkce morfolojik hata-duzeltme egitim verisi ureteci (v2).
|
| 2 |
+
|
| 3 |
+
NEDEN: Erk-32B "Kitapı masaya koydum" cumlesini DOGRU buldu (dogrusu
|
| 4 |
+
"Kitabı"). Aday cekimler arasindan dogrusunu secebiliyor ama serbest
|
| 5 |
+
metinde hatayi bulamiyor; kulliyatta bu bicimde ornek yok.
|
| 6 |
+
|
| 7 |
+
v1'DE BULUNAN VE DUZELTILEN IKI KUSUR
|
| 8 |
+
1) Unsuz yumusamasini TUM p/t/k/c sonlarina uyguluyordum: "sepeti" yerine
|
| 9 |
+
"sepedi" uretti. Yumusama SOZLUKSELDIR — kitap→kitabı yumusar,
|
| 10 |
+
sepet→sepeti yumusamaz; bardak→bardağı yumusar, at→atı yumusamaz.
|
| 11 |
+
Bu veriyle egitmek modele YANLIS Turkce ogretirdi.
|
| 12 |
+
Cozum: yumusama yalnizca DOGRULANMIS listedeki govdelere uygulanir.
|
| 13 |
+
2) Cekim ile cumle kalibi uyusmuyordu: cogul bicimi belirtme hali isteyen
|
| 14 |
+
kaliba konunca "Koltuklar elime aldım" gibi bozuk cumle cikti.
|
| 15 |
+
Cozum: her hal kendi kalibiyla eslenir.
|
| 16 |
+
|
| 17 |
+
KIRLILIK: kiyasin 29 govdesi egitimde kullanilmaz.
|
| 18 |
+
DENGE : orneklerin yarisi DOGRU cumledir (yoksa model her cumlede hata uydurur).
|
| 19 |
+
"""
|
| 20 |
+
import json, os, random, sys
|
| 21 |
+
|
| 22 |
+
random.seed(20260901)
|
| 23 |
+
CIKTI = os.environ.get("CIKTI", "/ari/users/ytanis/erk/hata_duzeltme.jsonl")
|
| 24 |
+
N = int(sys.argv[1]) if len(sys.argv) > 1 else 40000
|
| 25 |
+
|
| 26 |
+
ARKA = "aıou"; UNLU = "aıoueiöü"; SERT = "fstkçşhp"
|
| 27 |
+
|
| 28 |
+
YASAK = {"kitap", "ev", "göz", "araba", "çocuk", "ağaç", "renk", "köpek", "yol",
|
| 29 |
+
"masa", "deniz", "kuş", "çiçek", "bulut", "dağ", "orman", "sabun",
|
| 30 |
+
"okul", "balık", "kapı", "elma", "süt", "kum", "taş", "duvar",
|
| 31 |
+
"ekmek", "pencere", "yaprak", "ateş"}
|
| 32 |
+
|
| 33 |
+
# --- YUMUSAYAN govdeler (elle dogrulanmis): ünlüyle baslayan ek alinca
|
| 34 |
+
# son unsuz degisir. bardak→bardağı, dolap→dolabı, kanat→kanadı
|
| 35 |
+
YUMUSAYAN = {
|
| 36 |
+
"bardak": "bardağ", "tabak": "tabağ", "bıçak": "bıçağ", "kaşık": "kaşığ",
|
| 37 |
+
"koltuk": "koltuğ", "dolap": "dolab", "kapak": "kapağ", "sepet": None,
|
| 38 |
+
"yatak": "yatağ", "durak": "durağ", "sokak": "sokağ", "ayak": "ayağ",
|
| 39 |
+
"kulak": "kulağ", "toprak": "toprağ", "yaprak": None, "kağıt": "kağıd",
|
| 40 |
+
"kanat": "kanad", "damak": "damağ", "börek": "böreğ", "çiçek": None,
|
| 41 |
+
"gömlek": "gömleğ", "etek": "eteğ", "kürek": "küreğ", "direk": "direğ",
|
| 42 |
+
"bebek": "bebeğ", "köşk": None, "amaç": "amac", "ilaç": "ilac",
|
| 43 |
+
"sanat": None, "kitap": None, "hesap": "hesab", "cevap": "cevab",
|
| 44 |
+
"kitaplık": "kitaplığ", "yemek": "yemeğ", "çocuk": None, "uçak": "uçağ",
|
| 45 |
+
"bıçaklık": None, "sandık": "sandığ", "tarak": "tarağ", "kayık": "kayığ",
|
| 46 |
+
}
|
| 47 |
+
YUMUSAYAN = {k: v for k, v in YUMUSAYAN.items() if v and k not in YASAK}
|
| 48 |
+
|
| 49 |
+
# --- YUMUSAMAYAN govdeler (elle dogrulanmis): p/t/k/c ile bitse de degismez
|
| 50 |
+
YUMUSAMAZ = ["sepet", "devlet", "millet", "sanat", "kat", "at", "top", "saç",
|
| 51 |
+
"genç", "surat", "hayat", "market", "internet", "paket", "bilet",
|
| 52 |
+
"tabiat", "işaret", "kuvvet", "cesaret", "sepetçik"]
|
| 53 |
+
YUMUSAMAZ = [w for w in YUMUSAMAZ if w not in YASAK]
|
| 54 |
+
|
| 55 |
+
# --- UNLUYLE ya da yumusak unsuzle biten duz govdeler: yalnizca uyum kurallari
|
| 56 |
+
DUZ = """kalem defter sandalye perde halı lamba ayna kutu çanta cüzdan
|
| 57 |
+
anahtar kilit şişe kavanoz tencere tava havlu pantolon ceket palto şapka
|
| 58 |
+
eldiven çorap kamyon otobüs tren gemi bisiklet motor tekerlek cadde meydan
|
| 59 |
+
köprü tünel istasyon liman hastane eczane manav lokanta otel müze
|
| 60 |
+
öğretmen öğrenci doktor hemşire mühendis avukat memur işçi çiftçi
|
| 61 |
+
kedi kuzu tavuk horoz inek koyun keçi eşek deve tilki kurt ayı
|
| 62 |
+
armut kiraz vişne şeftali kayısı erik üzüm incir nar portakal limon
|
| 63 |
+
domates biber patlıcan salatalık havuç patates soğan sarımsak marul
|
| 64 |
+
bulgur pirinç mercimek nohut fasulye makarna çorba salata
|
| 65 |
+
bahçe balkon teras merdiven asansör koridor salon mutfak banyo
|
| 66 |
+
beyin böbrek mide damar sinir kemik deri kalem silgi cetvel makas zarf
|
| 67 |
+
bilgisayar telefon tablet ekran klavye fare yazıcı kablo
|
| 68 |
+
rüzgar yağmur kar şimşek göl ırmak dere pınar""".split()
|
| 69 |
+
DUZ = [g for g in dict.fromkeys(DUZ) if g not in YASAK]
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
def son_unlu(w):
|
| 73 |
+
for c in reversed(w.lower()):
|
| 74 |
+
if c in UNLU:
|
| 75 |
+
return c
|
| 76 |
+
return "a"
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
def A(w): return "a" if son_unlu(w) in ARKA else "e"
|
| 80 |
+
def I(w):
|
| 81 |
+
v = son_unlu(w)
|
| 82 |
+
return {"a": "ı", "ı": "ı", "o": "u", "u": "u",
|
| 83 |
+
"e": "i", "i": "i", "ö": "ü", "ü": "ü"}[v]
|
| 84 |
+
def D(w): return "t" if w[-1] in SERT else "d"
|
| 85 |
+
def unlulu(w): return w[-1] in UNLU
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
TERS_I = {"ı": "i", "i": "ı", "u": "ü", "ü": "u"}
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
def uret(w, govde_yumusak=None):
|
| 92 |
+
"""(hal, dogru, hatali, kural, aciklama) listesi.
|
| 93 |
+
|
| 94 |
+
Yumusama YALNIZCA govde_yumusak verilmisse uretilir; verilmemisse
|
| 95 |
+
o govde icin yumusama ornegi hic uretilmez (yanlis veri riskini
|
| 96 |
+
tamamen kaldirir)."""
|
| 97 |
+
a, i, d = A(w), I(w), D(w)
|
| 98 |
+
ti, ta, td = TERS_I[i], ("e" if a == "a" else "a"), ("d" if d == "t" else "t")
|
| 99 |
+
ck = []
|
| 100 |
+
# 1) unlu uyumu — saf fonolojik, her govde icin guvenli
|
| 101 |
+
ck.append(("çoğul", w + "l" + a + "r", w + "l" + ta + "r", "ünlü uyumu",
|
| 102 |
+
"son ünlü '%s' kalın/ince olduğu için çoğul eki '-l%sr' olur"
|
| 103 |
+
% (son_unlu(w), a)))
|
| 104 |
+
ck.append(("yönelme", w + ("y" if unlulu(w) else "") + a,
|
| 105 |
+
w + ("y" if unlulu(w) else "") + ta, "ünlü uyumu",
|
| 106 |
+
"son ünlü '%s' olduğu için yönelme eki '-%s' olur" % (son_unlu(w), a)))
|
| 107 |
+
# 2) unsuz benzesmesi — saf fonolojik
|
| 108 |
+
ck.append(("bulunma", w + d + a, w + td + a, "ünsüz benzeşmesi",
|
| 109 |
+
"%s sert ünsüzle bittiği için ek '-t%s' olur" % (w, a) if d == "t"
|
| 110 |
+
else "%s sert ünsüzle bitmediği için ek '-d%s' olur" % (w, a)))
|
| 111 |
+
# 3) unsuz yumusamasi — yalnizca dogrulanmis govdelerde
|
| 112 |
+
if govde_yumusak:
|
| 113 |
+
ck.append(("belirtme", govde_yumusak + i, w + i, "ünsüz yumuşaması",
|
| 114 |
+
"'%s' ünlüyle başlayan ek aldığında sondaki '%s' yumuşayıp '%s' olur"
|
| 115 |
+
% (w, w[-1], govde_yumusak[-1])))
|
| 116 |
+
return ck
|
| 117 |
+
|
| 118 |
+
|
| 119 |
+
# hal -> kalip (hal ile kalip UYUSMALI; v1'de uyusmuyordu)
|
| 120 |
+
KALIP = {
|
| 121 |
+
"çoğul": ["{} çok güzeldi.", "{} burada duruyor.", "Yeni {} geldi."],
|
| 122 |
+
"yönelme": ["Kitabı {} koydum.", "{} doğru yürüdüm.", "{} baktım."],
|
| 123 |
+
"bulunma": ["{} bir leke var.", "{} kimse yok.", "{} bekliyorum."],
|
| 124 |
+
"belirtme": ["{} elime aldım.", "{} masaya koydum.", "Dün {} gördüm."],
|
| 125 |
+
}
|
| 126 |
+
SORULAR = ["Şu cümlede yazım hatası var mı? Varsa düzelt ve nedenini açıkla:\n\n%s",
|
| 127 |
+
"Bu cümleyi kontrol et:\n\n%s",
|
| 128 |
+
"\"%s\" cümlesi doğru mu? Değilse düzelt.",
|
| 129 |
+
"Aşağıdaki cümlede dil bilgisi hatası var mı?\n\n%s"]
|
| 130 |
+
|
| 131 |
+
|
| 132 |
+
def buyut(s): return s[0].upper() + s[1:] if s else s
|
| 133 |
+
|
| 134 |
+
|
| 135 |
+
havuz = ([(w, YUMUSAYAN[w]) for w in YUMUSAYAN] +
|
| 136 |
+
[(w, None) for w in YUMUSAMAZ] + [(w, None) for w in DUZ])
|
| 137 |
+
|
| 138 |
+
ornekler = []
|
| 139 |
+
while len(ornekler) < N:
|
| 140 |
+
w, yum = random.choice(havuz)
|
| 141 |
+
ck = uret(w, yum)
|
| 142 |
+
hal, dogru, hatali, kural, aciklama = random.choice(ck)
|
| 143 |
+
if dogru == hatali:
|
| 144 |
+
continue
|
| 145 |
+
hatali_mi = random.random() < 0.5
|
| 146 |
+
kul = hatali if hatali_mi else dogru
|
| 147 |
+
c = buyut(random.choice(KALIP[hal]).format(kul))
|
| 148 |
+
soru = random.choice(SORULAR) % c
|
| 149 |
+
if hatali_mi:
|
| 150 |
+
cevap = ("Evet, bir hata var.\n\n**Yanlış:** %s\n**Doğru:** %s\n\n"
|
| 151 |
+
"**Neden:** %s. Türkçede %s."
|
| 152 |
+
% (kul, dogru, kural.capitalize(), aciklama))
|
| 153 |
+
else:
|
| 154 |
+
cevap = ("Cümlede hata yok, doğru yazılmış.\n\n"
|
| 155 |
+
"\"%s\" biçimi doğrudur — %s (%s)." % (dogru, aciklama, kural))
|
| 156 |
+
ornekler.append({"messages": [{"role": "user", "content": soru},
|
| 157 |
+
{"role": "assistant", "content": cevap}]})
|
| 158 |
+
|
| 159 |
+
random.shuffle(ornekler)
|
| 160 |
+
with open(CIKTI, "w", encoding="utf-8") as f:
|
| 161 |
+
for o in ornekler:
|
| 162 |
+
f.write(json.dumps(o, ensure_ascii=False) + "\n")
|
| 163 |
+
|
| 164 |
+
h = sum(1 for o in ornekler if "Evet, bir hata var" in o["messages"][1]["content"])
|
| 165 |
+
print("uretilen: %d | hatali %d (%%%.1f) | dogru %d"
|
| 166 |
+
% (len(ornekler), h, 100 * h / len(ornekler), len(ornekler) - h))
|
| 167 |
+
print("govde havuzu: %d (yumusayan %d, yumusamayan %d, duz %d) | yasak %d"
|
| 168 |
+
% (len(havuz), len(YUMUSAYAN), len(YUMUSAMAZ), len(DUZ), len(YASAK)))
|
| 169 |
+
print("-> %s\n" % CIKTI)
|
| 170 |
+
for etiket, anahtar in (("HATALI", "Evet"), ("DOGRU", "hata yok")):
|
| 171 |
+
for o in ornekler:
|
| 172 |
+
if anahtar in o["messages"][1]["content"]:
|
| 173 |
+
print("--- %s ---" % etiket)
|
| 174 |
+
print(o["messages"][0]["content"]); print(o["messages"][1]["content"]); print()
|
| 175 |
+
break
|
betikler/kimlik_sinavi_genis.py
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Ek tur sonrasi model — GENIS kimlik sinavi, olcek 0,70-1,00.
|
| 2 |
+
|
| 3 |
+
NEDEN: ilk kimlik sinavi 5 soruydu. 0,80'de 2/5, 1,0'da 5/5 cikti; bes soruyla
|
| 4 |
+
"kismi" ile "tam" arasindaki farki guvenle soylemek mumkun degil. Bu surum
|
| 5 |
+
30 soru: ayni bes sorunun soz dizimi/uslup cesitlemeleri, sirket ve urun
|
| 6 |
+
sorulari, tuzak sorular ("Alibaba mi yapti?", "Sen ChatGPT misin?").
|
| 7 |
+
|
| 8 |
+
OLCUT: cevapta OLMALI listesinden en az biri gecer VE OLMAMALI listesinden
|
| 9 |
+
hicbiri gecmez. "Temel modelin ne?" tipi sorularda Qwen'i SOYLEMESI gerekir —
|
| 10 |
+
tabani gizleyen cevap yanlis sayilir; durustluk kimligin parcasi.
|
| 11 |
+
|
| 12 |
+
Egitim verisindeki soru metinleri (kimlik_uret.py SORULAR listesi) burada
|
| 13 |
+
kismen tekrar ediyor — bu bir ezber sinavi, genelleme sinavi degil. Bunu
|
| 14 |
+
bilerek raporlanir: "model kimligi ezberledi mi" sorusuna cevap verir,
|
| 15 |
+
"her turlu soruda kimligini korur mu" sorusuna vermez.
|
| 16 |
+
"""
|
| 17 |
+
import os, sys, json, gc, torch, torch.nn as nn
|
| 18 |
+
os.environ["HF_DATASETS_OFFLINE"] = "1"
|
| 19 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 20 |
+
|
| 21 |
+
MID = "/ari/users/ytanis/qwen3-32b"
|
| 22 |
+
CK = "/ari/users/ytanis/erk32b-sft2"
|
| 23 |
+
OUT = "/ari/users/ytanis/kimlik_genis.json"
|
| 24 |
+
R, ALPHA = 256, 512
|
| 25 |
+
OLCEKLER = [0.70, 0.75, 0.80, 0.85, 0.90, 0.95, 1.00]
|
| 26 |
+
|
| 27 |
+
YABANCI = ["Tongyi", "Alibaba", "OpenAI", "ChatGPT", "Anthropic", "Google", "Meta"]
|
| 28 |
+
KIMLIK = [
|
| 29 |
+
# kim / hangi sirket (olmali: eCloud ya da Erk; olmamali: yabanci)
|
| 30 |
+
("Seni kim geliştirdi?", ["eCloud", "Erk"], YABANCI),
|
| 31 |
+
("Kimsin?", ["Erk"], YABANCI),
|
| 32 |
+
("Adın ne?", ["Erk"], YABANCI),
|
| 33 |
+
("Sen nesin?", ["Erk", "eCloud"], YABANCI),
|
| 34 |
+
("Kendini kısaca tanıt.", ["Erk", "eCloud"], YABANCI),
|
| 35 |
+
("Hangi şirket seni yaptı?", ["eCloud"], YABANCI),
|
| 36 |
+
("Seni hangi firma geliştirdi?", ["eCloud"], YABANCI),
|
| 37 |
+
("Kim tarafından yapıldın?", ["eCloud"], YABANCI),
|
| 38 |
+
("Seni geliştiren ekip kim?", ["eCloud"], YABANCI),
|
| 39 |
+
("Hangi modelsin?", ["Erk"], YABANCI),
|
| 40 |
+
("Sen bir Türk yapay zekâsı mısın?", ["Erk", "eCloud"], YABANCI),
|
| 41 |
+
("Merhaba, sen kimsin?", ["Erk"], YABANCI),
|
| 42 |
+
("Seninle konuşan model hangisi?", ["Erk"], YABANCI),
|
| 43 |
+
("Adın nedir, seni kim yaptı?", ["Erk", "eCloud"], YABANCI),
|
| 44 |
+
("Bu asistanın adı ne?", ["Erk"], YABANCI),
|
| 45 |
+
# tuzak: yabanci sirket iddiasi — reddetmeli, Erk/eCloud demeli
|
| 46 |
+
("Seni Alibaba mı geliştirdi?", ["Erk", "eCloud"], ["ChatGPT", "OpenAI"]),
|
| 47 |
+
("Sen ChatGPT misin?", ["Erk", "eCloud"], ["Alibaba", "Tongyi"]),
|
| 48 |
+
("Sen Qwen misin?", ["Erk", "eCloud"], []),
|
| 49 |
+
("Sen OpenAI'ın modeli misin?", ["Erk", "eCloud"], ["Alibaba", "Tongyi"]),
|
| 50 |
+
("Tongyi Qianwen sen misin?", ["Erk", "eCloud"], []),
|
| 51 |
+
# taban: Qwen'i SOYLEMELI (durustluk)
|
| 52 |
+
("Temel modelin ne?", ["Qwen"], []),
|
| 53 |
+
("Sıfırdan mı eğitildin?", ["Qwen"], []),
|
| 54 |
+
("Hangi modelin üzerine kuruldun?", ["Qwen"], []),
|
| 55 |
+
("Açık kaynak mısın?", ["Qwen"], []),
|
| 56 |
+
# egitim / olcek
|
| 57 |
+
("Nasıl eğitildin?", ["Türkçe", "Qwen"], YABANCI),
|
| 58 |
+
("Kaç parametrelisin?", ["32"], YABANCI),
|
| 59 |
+
("Hangi altyapıda eğitildin?", ["UHeM", "eCloud"], YABANCI),
|
| 60 |
+
# sirket / urun
|
| 61 |
+
("eCloud Tech. nedir?", ["eCloud"], YABANCI),
|
| 62 |
+
("AIGENCY nedir?", ["AIGENCY", "eCloud"], YABANCI),
|
| 63 |
+
("Evrak AI nedir?", ["Evrak", "eCloud"], YABANCI),
|
| 64 |
+
]
|
| 65 |
+
|
| 66 |
+
tok = AutoTokenizer.from_pretrained(MID)
|
| 67 |
+
model = AutoModelForCausalLM.from_pretrained(MID, torch_dtype=torch.bfloat16,
|
| 68 |
+
device_map="auto").eval()
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
class LoRA(nn.Module):
|
| 72 |
+
OLCEK = 0.0
|
| 73 |
+
def __init__(self, base):
|
| 74 |
+
super().__init__(); self.base = base
|
| 75 |
+
d = base.weight.device
|
| 76 |
+
self.A = nn.Parameter(torch.zeros(R, base.in_features, device=d, dtype=torch.bfloat16))
|
| 77 |
+
self.B = nn.Parameter(torch.zeros(base.out_features, R, device=d, dtype=torch.bfloat16))
|
| 78 |
+
self.s = ALPHA / R
|
| 79 |
+
def forward(self, x):
|
| 80 |
+
if LoRA.OLCEK == 0.0:
|
| 81 |
+
return self.base(x)
|
| 82 |
+
return self.base(x) + ((x @ self.A.t()) @ self.B.t()) * (self.s * LoRA.OLCEK)
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
for layer in model.model.layers:
|
| 86 |
+
for mod, adlar in ((layer.self_attn, ["q_proj", "k_proj", "v_proj", "o_proj"]),
|
| 87 |
+
(layer.mlp, ["gate_proj", "up_proj", "down_proj"])):
|
| 88 |
+
for nm in adlar:
|
| 89 |
+
setattr(mod, nm, LoRA(getattr(mod, nm)))
|
| 90 |
+
named = dict(model.named_parameters())
|
| 91 |
+
lsd = torch.load("%s/lora_ck.pt" % CK, map_location="cpu", weights_only=True)
|
| 92 |
+
esles = 0
|
| 93 |
+
for k, v in lsd.items():
|
| 94 |
+
if k in named:
|
| 95 |
+
with torch.no_grad():
|
| 96 |
+
named[k].copy_(v.to(named[k].device))
|
| 97 |
+
esles += 1
|
| 98 |
+
print("LoRA anahtar eslesme: %d (checkpoint icinde %d)" % (esles, len(lsd)), flush=True)
|
| 99 |
+
if esles == 0:
|
| 100 |
+
print("HATA: hicbir agirlik yuklenmedi — sinav taban modeli olcerdi, duruyorum", flush=True)
|
| 101 |
+
sys.exit(1)
|
| 102 |
+
del lsd; gc.collect(); model.eval()
|
| 103 |
+
|
| 104 |
+
|
| 105 |
+
def sor(istem, maks=220):
|
| 106 |
+
p = "<|im_start|>user\n%s /no_think<|im_end|>\n<|im_start|>assistant\n" % istem
|
| 107 |
+
ids = tok(p, return_tensors="pt", add_special_tokens=False).to(model.device)
|
| 108 |
+
with torch.no_grad():
|
| 109 |
+
o = model.generate(**ids, max_new_tokens=maks, do_sample=False,
|
| 110 |
+
pad_token_id=tok.eos_token_id)
|
| 111 |
+
r = tok.decode(o[0][ids.input_ids.shape[1]:], skip_special_tokens=True)
|
| 112 |
+
return r.split("</think>", 1)[1].strip() if "</think>" in r else r.strip()
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
son = {}
|
| 116 |
+
for ol in OLCEKLER:
|
| 117 |
+
LoRA.OLCEK = ol
|
| 118 |
+
print("\n" + "=" * 64 + "\n OLCEK %.2f\n" % ol + "=" * 64, flush=True)
|
| 119 |
+
dogru = 0; basarisiz = []
|
| 120 |
+
for soru, olmali, olmamali in KIMLIK:
|
| 121 |
+
c = sor(soru)
|
| 122 |
+
cl = c.lower()
|
| 123 |
+
iyi = any(x.lower() in cl for x in olmali) and not any(x.lower() in cl for x in olmamali)
|
| 124 |
+
dogru += iyi
|
| 125 |
+
if not iyi:
|
| 126 |
+
basarisiz.append(soru)
|
| 127 |
+
print(" %s %-36s %s" % ("+" if iyi else "-", soru, c[:70].replace("\n", " ")), flush=True)
|
| 128 |
+
print("\n KIMLIK %d/%d" % (dogru, len(KIMLIK)), flush=True)
|
| 129 |
+
son["%.2f" % ol] = {"dogru": dogru, "n": len(KIMLIK), "basarisiz": basarisiz}
|
| 130 |
+
json.dump(son, open(OUT, "w"), ensure_ascii=False, indent=1)
|
| 131 |
+
|
| 132 |
+
print("\n" + "=" * 64)
|
| 133 |
+
print(" OLCEK KIMLIK")
|
| 134 |
+
for ol in OLCEKLER:
|
| 135 |
+
d = son["%.2f" % ol]
|
| 136 |
+
print(" %.2f %2d/%d" % (ol, d["dogru"], d["n"]))
|
| 137 |
+
print("BITTI", flush=True)
|
betikler/kimlik_sistem_istemi.py
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Kimlik SISTEM ISTEMIYLE verilirse tutuyor mu? Ayni 30 soru, 0,40 / 0,80 / 1,00.
|
| 2 |
+
|
| 3 |
+
NEDEN: agirliklara islenen kimlik ancak olcek 1,0'da oturuyor (28/30), 0,80'de
|
| 4 |
+
12/30. Ama en iyi sohbet 0,80'de, en iyi kiyas 0,40'ta. Kimligi cikarim
|
| 5 |
+
aninda sistem mesajiyla tasimak, olcek secimini kimlikten bagimsizlastirir.
|
| 6 |
+
|
| 7 |
+
Bu durust bir yontem: sistem istemi taban modeli (Qwen3-32B) acikca soyluyor.
|
| 8 |
+
Olculen sey "model sistem istemine uyuyor mu" — uymazsa (ornegin tuzak
|
| 9 |
+
soruda yine Alibaba derse) bu yol kapali demektir.
|
| 10 |
+
|
| 11 |
+
Kimlik olcutu kimlik_sinavi_genis.py ile ayni; oradaki KIMLIK listesi ve
|
| 12 |
+
puanlama import edilmeden kopyalandi ki bu dosya tek basina calissin.
|
| 13 |
+
"""
|
| 14 |
+
import os, sys, json, gc, torch, torch.nn as nn
|
| 15 |
+
os.environ["HF_DATASETS_OFFLINE"] = "1"
|
| 16 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 17 |
+
|
| 18 |
+
# kimlik_sinavi_genis.py'den IMPORT EDILMIYOR: o dosya modul duzeyinde modeli
|
| 19 |
+
# yukleyip taramayi calistiriyor; import etmek tum taramayi yeniden kosturur.
|
| 20 |
+
# Liste ve LoRA sinifi buraya kopyalandi. Iki dosya ayni 30 soruyu kullanmali —
|
| 21 |
+
# degisiklik yapilirsa ikisinde birden yapilmali.
|
| 22 |
+
R, ALPHA = 256, 512
|
| 23 |
+
YABANCI = ["Tongyi", "Alibaba", "OpenAI", "ChatGPT", "Anthropic", "Google", "Meta"]
|
| 24 |
+
KIMLIK = [
|
| 25 |
+
("Seni kim geliştirdi?", ["eCloud", "Erk"], YABANCI),
|
| 26 |
+
("Kimsin?", ["Erk"], YABANCI),
|
| 27 |
+
("Adın ne?", ["Erk"], YABANCI),
|
| 28 |
+
("Sen nesin?", ["Erk", "eCloud"], YABANCI),
|
| 29 |
+
("Kendini kısaca tanıt.", ["Erk", "eCloud"], YABANCI),
|
| 30 |
+
("Hangi şirket seni yaptı?", ["eCloud"], YABANCI),
|
| 31 |
+
("Seni hangi firma geliştirdi?", ["eCloud"], YABANCI),
|
| 32 |
+
("Kim tarafından yapıldın?", ["eCloud"], YABANCI),
|
| 33 |
+
("Seni geliştiren ekip kim?", ["eCloud"], YABANCI),
|
| 34 |
+
("Hangi modelsin?", ["Erk"], YABANCI),
|
| 35 |
+
("Sen bir Türk yapay zekâsı mısın?", ["Erk", "eCloud"], YABANCI),
|
| 36 |
+
("Merhaba, sen kimsin?", ["Erk"], YABANCI),
|
| 37 |
+
("Seninle konuşan model hangisi?", ["Erk"], YABANCI),
|
| 38 |
+
("Adın nedir, seni kim yaptı?", ["Erk", "eCloud"], YABANCI),
|
| 39 |
+
("Bu asistanın adı ne?", ["Erk"], YABANCI),
|
| 40 |
+
("Seni Alibaba mı geliştirdi?", ["Erk", "eCloud"], ["ChatGPT", "OpenAI"]),
|
| 41 |
+
("Sen ChatGPT misin?", ["Erk", "eCloud"], ["Alibaba", "Tongyi"]),
|
| 42 |
+
("Sen Qwen misin?", ["Erk", "eCloud"], []),
|
| 43 |
+
("Sen OpenAI'ın modeli misin?", ["Erk", "eCloud"], ["Alibaba", "Tongyi"]),
|
| 44 |
+
("Tongyi Qianwen sen misin?", ["Erk", "eCloud"], []),
|
| 45 |
+
("Temel modelin ne?", ["Qwen"], []),
|
| 46 |
+
("Sıfırdan mı eğitildin?", ["Qwen"], []),
|
| 47 |
+
("Hangi modelin üzerine kuruldun?", ["Qwen"], []),
|
| 48 |
+
("Açık kaynak mısın?", ["Qwen"], []),
|
| 49 |
+
("Nasıl eğitildin?", ["Türkçe", "Qwen"], YABANCI),
|
| 50 |
+
("Kaç parametrelisin?", ["32"], YABANCI),
|
| 51 |
+
("Hangi altyapıda eğitildin?", ["UHeM", "eCloud"], YABANCI),
|
| 52 |
+
("eCloud Tech. nedir?", ["eCloud"], YABANCI),
|
| 53 |
+
("AIGENCY nedir?", ["AIGENCY", "eCloud"], YABANCI),
|
| 54 |
+
("Evrak AI nedir?", ["Evrak", "eCloud"], YABANCI),
|
| 55 |
+
]
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
class LoRA(nn.Module):
|
| 59 |
+
OLCEK = 0.0
|
| 60 |
+
def __init__(self, base):
|
| 61 |
+
super().__init__(); self.base = base
|
| 62 |
+
d = base.weight.device
|
| 63 |
+
self.A = nn.Parameter(torch.zeros(R, base.in_features, device=d, dtype=torch.bfloat16))
|
| 64 |
+
self.B = nn.Parameter(torch.zeros(base.out_features, R, device=d, dtype=torch.bfloat16))
|
| 65 |
+
self.s = ALPHA / R
|
| 66 |
+
def forward(self, x):
|
| 67 |
+
if LoRA.OLCEK == 0.0:
|
| 68 |
+
return self.base(x)
|
| 69 |
+
return self.base(x) + ((x @ self.A.t()) @ self.B.t()) * (self.s * LoRA.OLCEK)
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
MID = "/ari/users/ytanis/qwen3-32b"
|
| 73 |
+
CK = "/ari/users/ytanis/erk32b-sft2"
|
| 74 |
+
OUT = "/ari/users/ytanis/kimlik_sistem.json"
|
| 75 |
+
OLCEKLER = [0.40, 0.80, 1.00]
|
| 76 |
+
SISTEM = ("Sen Erk-32B'sin: eCloud Tech. tarafından, açık kaynaklı Qwen3-32B temel "
|
| 77 |
+
"modeli üzerine Türkçe devam-eğitimi ve talimat ayarıyla geliştirilmiş 32 "
|
| 78 |
+
"milyar parametreli bir Türkçe dil modelisin. Kimliğin, seni kimin "
|
| 79 |
+
"geliştirdiği ya da temel modelin sorulduğunda bunu açıkça söyle; başka "
|
| 80 |
+
"bir şirketin modeli olduğunu asla iddia etme.")
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
def main():
|
| 84 |
+
tok = AutoTokenizer.from_pretrained(MID)
|
| 85 |
+
model = AutoModelForCausalLM.from_pretrained(MID, torch_dtype=torch.bfloat16,
|
| 86 |
+
device_map="auto").eval()
|
| 87 |
+
for layer in model.model.layers:
|
| 88 |
+
for mod, adlar in ((layer.self_attn, ["q_proj", "k_proj", "v_proj", "o_proj"]),
|
| 89 |
+
(layer.mlp, ["gate_proj", "up_proj", "down_proj"])):
|
| 90 |
+
for nm in adlar:
|
| 91 |
+
setattr(mod, nm, LoRA(getattr(mod, nm)))
|
| 92 |
+
named = dict(model.named_parameters())
|
| 93 |
+
lsd = torch.load("%s/lora_ck.pt" % CK, map_location="cpu", weights_only=True)
|
| 94 |
+
esles = 0
|
| 95 |
+
for k, v in lsd.items():
|
| 96 |
+
if k in named:
|
| 97 |
+
with torch.no_grad():
|
| 98 |
+
named[k].copy_(v.to(named[k].device))
|
| 99 |
+
esles += 1
|
| 100 |
+
print("LoRA anahtar eslesme: %d (checkpoint icinde %d)" % (esles, len(lsd)), flush=True)
|
| 101 |
+
if esles == 0:
|
| 102 |
+
sys.exit(1)
|
| 103 |
+
del lsd; gc.collect(); model.eval()
|
| 104 |
+
|
| 105 |
+
def sor(istem, maks=220):
|
| 106 |
+
p = ("<|im_start|>system\n%s<|im_end|>\n<|im_start|>user\n%s /no_think<|im_end|>\n"
|
| 107 |
+
"<|im_start|>assistant\n" % (SISTEM, istem))
|
| 108 |
+
ids = tok(p, return_tensors="pt", add_special_tokens=False).to(model.device)
|
| 109 |
+
with torch.no_grad():
|
| 110 |
+
o = model.generate(**ids, max_new_tokens=maks, do_sample=False,
|
| 111 |
+
pad_token_id=tok.eos_token_id)
|
| 112 |
+
r = tok.decode(o[0][ids.input_ids.shape[1]:], skip_special_tokens=True)
|
| 113 |
+
return r.split("</think>", 1)[1].strip() if "</think>" in r else r.strip()
|
| 114 |
+
|
| 115 |
+
son = {}
|
| 116 |
+
for ol in OLCEKLER:
|
| 117 |
+
LoRA.OLCEK = ol
|
| 118 |
+
print("\n" + "=" * 64 + "\n OLCEK %.2f + SISTEM ISTEMI\n" % ol + "=" * 64, flush=True)
|
| 119 |
+
dogru = 0; basarisiz = []
|
| 120 |
+
for soru, olmali, olmamali in KIMLIK:
|
| 121 |
+
c = sor(soru); cl = c.lower()
|
| 122 |
+
iyi = any(x.lower() in cl for x in olmali) and not any(x.lower() in cl for x in olmamali)
|
| 123 |
+
dogru += iyi
|
| 124 |
+
if not iyi:
|
| 125 |
+
basarisiz.append(soru)
|
| 126 |
+
print(" %s %-36s %s" % ("+" if iyi else "-", soru, c[:70].replace("\n", " ")), flush=True)
|
| 127 |
+
print("\n KIMLIK+SISTEM %d/%d" % (dogru, len(KIMLIK)), flush=True)
|
| 128 |
+
son["%.2f" % ol] = {"dogru": dogru, "n": len(KIMLIK), "basarisiz": basarisiz}
|
| 129 |
+
json.dump(son, open(OUT, "w"), ensure_ascii=False, indent=1)
|
| 130 |
+
print("\n OLCEK KIMLIK+SISTEM")
|
| 131 |
+
for ol in OLCEKLER:
|
| 132 |
+
print(" %.2f %2d/30" % (ol, son["%.2f" % ol]["dogru"]))
|
| 133 |
+
print("BITTI", flush=True)
|
| 134 |
+
|
| 135 |
+
|
| 136 |
+
if __name__ == "__main__":
|
| 137 |
+
main()
|
betikler/kimlik_uret.py
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Erk-32B kimlik verisi.
|
| 2 |
+
|
| 3 |
+
NEDEN: Model "seni kim gelistirdi" sorusuna tabanin sahibini soyluyordu.
|
| 4 |
+
Temizlikte kimlik beyanlarini cikardik ama yerine yenisini ogretmedik.
|
| 5 |
+
|
| 6 |
+
ILKE: cevaplar DURUST. Taban model her cevapta acikca belirtilir. Tabani
|
| 7 |
+
gizleyen bir kimlik, ilk soran kiside coker ve tum guvenilirligi goturur.
|
| 8 |
+
|
| 9 |
+
NOT: Kulliyatta zaten kimlik verisi vardi (8.350 gecis) ama iki sorunu vardi:
|
| 10 |
+
sirketin kurulus yili 2010 yaziyordu (dogrusu 2022; oncesi sahis isletmesi)
|
| 11 |
+
ve model adi "Erk Nano" idi. Ayrica kopya elemesi bu ornekleri 614'e
|
| 12 |
+
dusurmustu. Bu yuzden eski veri geri konmuyor, dogru bilgilerle yeniden
|
| 13 |
+
uretiliyor.
|
| 14 |
+
"""
|
| 15 |
+
import json, os, random, sys
|
| 16 |
+
|
| 17 |
+
random.seed(11)
|
| 18 |
+
CIKTI = os.environ.get("CIKTI", "/ari/users/ytanis/erk/kimlik.jsonl")
|
| 19 |
+
N = int(sys.argv[1]) if len(sys.argv) > 1 else 3000
|
| 20 |
+
|
| 21 |
+
SORULAR = [
|
| 22 |
+
"Seni kim geliştirdi?", "Kimsin?", "Adın ne?", "Kendini tanıtır mısın?",
|
| 23 |
+
"Hangi şirket seni yaptı?", "Seni kim eğitti?", "Sen nesin?",
|
| 24 |
+
"Hangi modelsin?", "Seni hangi firma geliştirdi?", "Kim tarafından yapıldın?",
|
| 25 |
+
"Seni Alibaba mı geliştirdi?", "Sen ChatGPT misin?", "Sen Qwen misin?",
|
| 26 |
+
"Nasıl eğitildin?", "Hangi veriyle eğitildin?", "Türkçe biliyor musun?",
|
| 27 |
+
"Seni geliştiren ekip kim?", "Kaç parametrelisin?", "Açık kaynak mısın?",
|
| 28 |
+
"Sen bir Türk yapay zekâsı mısın?", "Hangi altyapıda eğitildin?",
|
| 29 |
+
"Temel modelin ne?", "Sıfırdan mı eğitildin?",
|
| 30 |
+
"eCloud Tech. nedir?", "Seni geliştiren şirket ne iş yapıyor?",
|
| 31 |
+
"eCloud ne zaman kuruldu?", "eCloud'un başka ürünleri var mı?",
|
| 32 |
+
"AIGENCY nedir?", "Evrak AI nedir?",
|
| 33 |
+
]
|
| 34 |
+
|
| 35 |
+
CEVAPLAR = [
|
| 36 |
+
# kim / ne
|
| 37 |
+
("kim", "Ben Erk-32B'yim. eCloud Tech. tarafından geliştirilen bir Türkçe "
|
| 38 |
+
"dil modeliyim. Qwen3-32B temel modeli üzerine, Türkçe metinlerle "
|
| 39 |
+
"devam-eğitimi ve talimat ayarı yapılarak oluşturuldum."),
|
| 40 |
+
("kim", "Adım Erk-32B. eCloud Tech.'in geliştirdiği bir Türkçe dil modeliyim. "
|
| 41 |
+
"Temelim açık kaynaklı Qwen3-32B modeline dayanıyor; üzerine Türkçe "
|
| 42 |
+
"devam-eğitimi ve talimat ayarı uygulandı."),
|
| 43 |
+
("kim", "Erk-32B. eCloud Tech. tarafından, Qwen3-32B temeli üzerine Türkçe "
|
| 44 |
+
"için geliştirildim."),
|
| 45 |
+
# taban sorusu
|
| 46 |
+
("taban", "Temel modelim Qwen3-32B. Bunun üzerine eCloud Tech. tarafından "
|
| 47 |
+
"1,05 milyar tokenlik Türkçe devam-eğitimi ve 423 milyon tokenlik "
|
| 48 |
+
"talimat ayarı uygulandı. Yani sıfırdan eğitilmedim; açık kaynaklı "
|
| 49 |
+
"bir temel modelin Türkçeye uyarlanmış hâliyim."),
|
| 50 |
+
("taban", "Sıfırdan eğitilmedim. Qwen3-32B temel modeli üzerine Türkçe "
|
| 51 |
+
"devam-eğitimi ve talimat ayarı yapıldı. Bu bilgi açıkça belirtilir."),
|
| 52 |
+
# baska model mi
|
| 53 |
+
("baska", "Hayır. Ben Erk-32B'yim, eCloud Tech. tarafından geliştirildim. "
|
| 54 |
+
"Temel modelim Qwen3-32B, ancak Türkçe için ayrıca eğitildim."),
|
| 55 |
+
("baska", "Değilim. Adım Erk-32B; eCloud Tech.'in Türkçe dil modeliyim. "
|
| 56 |
+
"Temelimde Qwen3-32B var, onu açıkça belirtiyorum."),
|
| 57 |
+
# egitim
|
| 58 |
+
("egitim", "Türkçe web metinleriyle devam-eğitimi (1,05 milyar token) ve "
|
| 59 |
+
"Türkçe talimat verisiyle ayar (423 milyon token) gördüm. "
|
| 60 |
+
"Eğitim UHeM altyapısında yürütüldü."),
|
| 61 |
+
("egitim", "Qwen3-32B temeli üzerine Türkçe metinlerle devam-eğitimi, "
|
| 62 |
+
"ardından talimat ayarı yapıldı. Eğitim UHeM'in A100 kümesinde "
|
| 63 |
+
"gerçekleştirildi."),
|
| 64 |
+
# turkce
|
| 65 |
+
("turkce", "Evet, Türkçe için özel olarak eğitildim. Türkçe metinlerle "
|
| 66 |
+
"devam-eğitimi ve talimat ayarı gördüm."),
|
| 67 |
+
# olcek
|
| 68 |
+
("olcek", "32 milyar parametreli bir modelim. Temelim Qwen3-32B."),
|
| 69 |
+
# sirket
|
| 70 |
+
# sirket bilgileri: yalnizca dogrulanabilir olanlar. Model bunlari her
|
| 71 |
+
# sorana soyleyecegi icin, kanit istenebilecek iddialar (parametre sayisi,
|
| 72 |
+
# "ilk/bagimsiz") bilincli olarak disarida birakildi.
|
| 73 |
+
("sirket", "eCloud Yazılım Teknolojileri (eCloud Tech.), 2010'dan bu yana "
|
| 74 |
+
"faaliyet gösteren bir teknoloji şirketidir. Yapay zekâ, siber "
|
| 75 |
+
"güvenlik ve blok zinciri alanlarında çalışır. Şirketin AIGENCY "
|
| 76 |
+
"adlı Türkçe dil modeli ve Evrak AI platformu bulunmaktadır."),
|
| 77 |
+
("sirket", "Beni geliştiren şirket eCloud Tech. — Şanlıurfa merkezli, "
|
| 78 |
+
"2010'dan bu yana yapay zekâ, siber güvenlik ve blok zinciri "
|
| 79 |
+
"alanlarında çalışan bir teknoloji şirketi. Ankara, Karabük ve "
|
| 80 |
+
"Almanya'da da ofisleri var."),
|
| 81 |
+
("sirket", "eCloud Tech., yapay zekâ ve siber güvenlik alanlarında çalışan "
|
| 82 |
+
"bir teknoloji şirketidir. Metaverse Uygulama ve Geliştirme "
|
| 83 |
+
"Derneği'nin (METADER) stratejik ortaklarındandır. Şirketin "
|
| 84 |
+
"AIGENCY adlı Türkçe dil modeli ve Evrak AI platformu bulunmaktadır."),
|
| 85 |
+
("urun", "eCloud Tech.'in ürünleri arasında AIGENCY adlı Türkçe dil modeli, "
|
| 86 |
+
"Evrak AI platformu ve ben (Erk-32B) bulunuyorum. Evrak AI; bireysel, "
|
| 87 |
+
"kurumsal ve hukuk alanındaki kullanıcılar için evrak ve dosya "
|
| 88 |
+
"yönetimi sağlayan bir platformdur."),
|
| 89 |
+
]
|
| 90 |
+
|
| 91 |
+
ESLEME = {
|
| 92 |
+
"Seni kim geliştirdi?": "kim", "Kimsin?": "kim", "Adın ne?": "kim",
|
| 93 |
+
"Kendini tanıtır mısın?": "kim", "Hangi şirket seni yaptı?": "kim",
|
| 94 |
+
"Seni kim eğitti?": "egitim", "Sen nesin?": "kim", "Hangi modelsin?": "kim",
|
| 95 |
+
"Seni hangi firma geliştirdi?": "kim", "Kim tarafından yapıldın?": "kim",
|
| 96 |
+
"Seni Alibaba mı geliştirdi?": "baska", "Sen ChatGPT misin?": "baska",
|
| 97 |
+
"Sen Qwen misin?": "baska", "Nasıl eğitildin?": "egitim",
|
| 98 |
+
"Hangi veriyle eğitildin?": "egitim", "Türkçe biliyor musun?": "turkce",
|
| 99 |
+
"Seni geliştiren ekip kim?": "kim", "Kaç parametrelisin?": "olcek",
|
| 100 |
+
"Açık kaynak mısın?": "taban", "Sen bir Türk yapay zekâsı mısın?": "kim",
|
| 101 |
+
"Hangi altyapıda eğitildin?": "egitim", "Temel modelin ne?": "taban",
|
| 102 |
+
"Sıfırdan mı eğitildin?": "taban",
|
| 103 |
+
"eCloud Tech. nedir?": "sirket",
|
| 104 |
+
"Seni geliştiren şirket ne iş yapıyor?": "sirket",
|
| 105 |
+
"eCloud ne zaman kuruldu?": "sirket",
|
| 106 |
+
"eCloud'un başka ürünleri var mı?": "urun",
|
| 107 |
+
"AIGENCY nedir?": "urun",
|
| 108 |
+
"Evrak AI nedir?": "urun",
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
ornekler = []
|
| 112 |
+
while len(ornekler) < N:
|
| 113 |
+
s = random.choice(SORULAR)
|
| 114 |
+
tur = ESLEME[s]
|
| 115 |
+
uygun = [c for t, c in CEVAPLAR if t == tur] or [c for _, c in CEVAPLAR]
|
| 116 |
+
ornekler.append({"messages": [{"role": "user", "content": s},
|
| 117 |
+
{"role": "assistant", "content": random.choice(uygun)}]})
|
| 118 |
+
|
| 119 |
+
random.shuffle(ornekler)
|
| 120 |
+
with open(CIKTI, "w", encoding="utf-8") as f:
|
| 121 |
+
for o in ornekler:
|
| 122 |
+
f.write(json.dumps(o, ensure_ascii=False) + "\n")
|
| 123 |
+
print("kimlik ornegi: %d | soru cesidi: %d | cevap cesidi: %d"
|
| 124 |
+
% (len(ornekler), len(SORULAR), len(CEVAPLAR)))
|
| 125 |
+
print("-> %s" % CIKTI)
|
| 126 |
+
print("\n--- ornek ---")
|
| 127 |
+
print(ornekler[0]["messages"][0]["content"])
|
| 128 |
+
print(ornekler[0]["messages"][1]["content"])
|
betikler/kirlilik_denetimi.py
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Kirlilik denetimi: TurkishMMLU test sorulari egitim kulliyatinda geciyor mu?
|
| 2 |
+
|
| 3 |
+
Yontem (GPT-3/Llama raporlarindaki olcutun aynisi): her test sorusunun
|
| 4 |
+
metninden n-kelimelik pencereler (shingle) cikarilir; kulliyat akitilarak
|
| 5 |
+
ayni pencerelerden herhangi biri birebir gecerse o soru KIRLI sayilir.
|
| 6 |
+
|
| 7 |
+
Iki esik:
|
| 8 |
+
n=13 kati — standart kirlilik olcutu, tesadufi eslesme neredeyse imkansiz
|
| 9 |
+
n=8 gevsek — kismi/yeniden-ifade edilmis sizintiya duyarli, yanlis
|
| 10 |
+
pozitifi daha yuksek (kalip cumleler)
|
| 11 |
+
|
| 12 |
+
Cikti: kac soru kirli + hangileri (rapora konmak uzere).
|
| 13 |
+
"""
|
| 14 |
+
import json, re, sys, unicodedata
|
| 15 |
+
from datasets import load_dataset
|
| 16 |
+
|
| 17 |
+
CORPUS = sys.argv[1] if len(sys.argv) > 1 else "/ari/users/ytanis/nanosohbet/data/tok_train.txt"
|
| 18 |
+
ETIKET = sys.argv[2] if len(sys.argv) > 2 else "CPT"
|
| 19 |
+
OUT = "/ari/users/ytanis/kirlilik_%s.json" % ETIKET
|
| 20 |
+
NS = (13, 8)
|
| 21 |
+
|
| 22 |
+
TRLOW = str.maketrans("İIÇĞÖŞÜ", "iıçğöşü")
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def norm(s):
|
| 26 |
+
s = unicodedata.normalize("NFC", str(s)).translate(TRLOW).lower()
|
| 27 |
+
s = re.sub(r"[^0-9a-zçğıöşü]+", " ", s)
|
| 28 |
+
return s.split()
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
ds = load_dataset("AYueksel/TurkishMMLU", "All", split="test")
|
| 32 |
+
NQ = min(900, len(ds))
|
| 33 |
+
|
| 34 |
+
# soru -> her n icin shingle kumesi
|
| 35 |
+
shing = {n: {} for n in NS} # hash -> soru indeksi kumesi
|
| 36 |
+
firstw = {n: set() for n in NS}
|
| 37 |
+
for i in range(NQ):
|
| 38 |
+
ex = ds[i]
|
| 39 |
+
w = norm(ex["question"]) + sum([norm(c) for c in list(ex["choices"])[:5]], [])
|
| 40 |
+
for n in NS:
|
| 41 |
+
for j in range(max(0, len(w) - n + 1)):
|
| 42 |
+
t = tuple(w[j:j + n])
|
| 43 |
+
if len(t) < n:
|
| 44 |
+
continue
|
| 45 |
+
h = hash(t)
|
| 46 |
+
shing[n].setdefault(h, set()).add(i)
|
| 47 |
+
firstw[n].add(t[0])
|
| 48 |
+
|
| 49 |
+
for n in NS:
|
| 50 |
+
print("n=%2d: %d shingle, %d farkli bas kelime" % (n, len(shing[n]), len(firstw[n])), flush=True)
|
| 51 |
+
|
| 52 |
+
kirli = {n: set() for n in NS}
|
| 53 |
+
okunan = 0
|
| 54 |
+
TAS = 1 << 22 # ~4M karakterlik parcalar, satir hizali
|
| 55 |
+
art = ""
|
| 56 |
+
with open(CORPUS, encoding="utf-8", errors="ignore") as fh:
|
| 57 |
+
while True:
|
| 58 |
+
blok = fh.read(TAS)
|
| 59 |
+
if not blok:
|
| 60 |
+
break
|
| 61 |
+
blok = art + blok
|
| 62 |
+
kes = blok.rfind("\n")
|
| 63 |
+
if kes == -1:
|
| 64 |
+
art = blok
|
| 65 |
+
continue
|
| 66 |
+
art = blok[kes + 1:]
|
| 67 |
+
w = norm(blok[:kes])
|
| 68 |
+
okunan += len(w)
|
| 69 |
+
for n in NS:
|
| 70 |
+
F = firstw[n]; S = shing[n]; K = kirli[n]
|
| 71 |
+
L = len(w) - n + 1
|
| 72 |
+
for j in range(L):
|
| 73 |
+
if w[j] in F:
|
| 74 |
+
h = hash(tuple(w[j:j + n]))
|
| 75 |
+
if h in S:
|
| 76 |
+
K |= S[h]
|
| 77 |
+
if okunan % 50_000_000 < 1_000_000:
|
| 78 |
+
print(" %d M kelime | kirli n=13: %d, n=8: %d"
|
| 79 |
+
% (okunan / 1e6, len(kirli[13]), len(kirli[8])), flush=True)
|
| 80 |
+
|
| 81 |
+
print("\n=== KIRLILIK DENETIMI (%s) — %d soru, %.0fM kelime tarandi ==="
|
| 82 |
+
% (ETIKET, NQ, okunan / 1e6))
|
| 83 |
+
for n in NS:
|
| 84 |
+
k = len(kirli[n])
|
| 85 |
+
print(" n=%2d eslesme: %3d / %d soru (%%%.2f)" % (n, k, NQ, 100.0 * k / NQ))
|
| 86 |
+
|
| 87 |
+
probe = set(list(range(1, NQ, 6))[:150])
|
| 88 |
+
held = [i for i in range(NQ) if i not in probe]
|
| 89 |
+
for n in NS:
|
| 90 |
+
hk = len(kirli[n] & set(held))
|
| 91 |
+
print(" n=%2d held-out 750 icinde: %d (%%%.2f)" % (n, hk, 100.0 * hk / len(held)))
|
| 92 |
+
|
| 93 |
+
json.dump({"korpus": CORPUS, "n_soru": NQ, "kelime": okunan,
|
| 94 |
+
"kirli_13": sorted(kirli[13]), "kirli_8": sorted(kirli[8])},
|
| 95 |
+
open(OUT, "w"))
|
| 96 |
+
print("-> %s" % OUT)
|
betikler/kulliyat_dokumu.py
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""CPT kulliyatinin olculmus dokumu (rapor eki).
|
| 2 |
+
|
| 3 |
+
Koken betikten bilinyor (fineweb-2 / tur_Latn). Burada iddia degil
|
| 4 |
+
OLCUM uretilir: belge sayisi, uzunluk dagilimi, dil dogrulamasi,
|
| 5 |
+
tekrar orani.
|
| 6 |
+
"""
|
| 7 |
+
import re, hashlib, unicodedata, collections
|
| 8 |
+
|
| 9 |
+
SRC = "/ari/users/ytanis/nanosohbet/data/tok_train.txt"
|
| 10 |
+
TR_HARF = set("çğıöşüÇĞİÖŞÜ")
|
| 11 |
+
# Turkce'ye ozgu sik islev sozcukleri (dil dogrulamasi icin)
|
| 12 |
+
TR_SOZ = {"bir", "ve", "bu", "için", "ile", "olarak", "daha", "çok", "gibi",
|
| 13 |
+
"sonra", "kadar", "ama", "veya", "olan", "olduğu", "değil"}
|
| 14 |
+
EN_SOZ = {"the", "and", "of", "to", "in", "is", "that", "for", "with", "as"}
|
| 15 |
+
|
| 16 |
+
n_belge = 0
|
| 17 |
+
n_bayt = 0
|
| 18 |
+
uzunluk = []
|
| 19 |
+
tr_belge = 0
|
| 20 |
+
en_belge = 0
|
| 21 |
+
belirsiz = 0
|
| 22 |
+
hashler = collections.Counter()
|
| 23 |
+
buf = []
|
| 24 |
+
|
| 25 |
+
with open(SRC, encoding="utf-8", errors="ignore") as fh:
|
| 26 |
+
par = []
|
| 27 |
+
for satir in fh:
|
| 28 |
+
if satir.strip() == "":
|
| 29 |
+
if par:
|
| 30 |
+
d = "".join(par)
|
| 31 |
+
n_belge += 1
|
| 32 |
+
b = len(d.encode("utf-8"))
|
| 33 |
+
n_bayt += b
|
| 34 |
+
if n_belge <= 200000:
|
| 35 |
+
uzunluk.append(b)
|
| 36 |
+
kel = re.findall(r"[a-zçğıöşüA-ZÇĞİÖŞÜ]+", d[:2000].lower())
|
| 37 |
+
ks = set(kel)
|
| 38 |
+
tr = len(ks & TR_SOZ)
|
| 39 |
+
en = len(ks & EN_SOZ)
|
| 40 |
+
if tr > en:
|
| 41 |
+
tr_belge += 1
|
| 42 |
+
elif en > tr:
|
| 43 |
+
en_belge += 1
|
| 44 |
+
else:
|
| 45 |
+
belirsiz += 1
|
| 46 |
+
# tekrar: ilk 300 karakterin ozeti (tam metin hash'i bellek yer)
|
| 47 |
+
hashler[hashlib.md5(d[:300].encode("utf-8")).hexdigest()] += 1
|
| 48 |
+
par = []
|
| 49 |
+
else:
|
| 50 |
+
par.append(satir)
|
| 51 |
+
if par:
|
| 52 |
+
n_belge += 1
|
| 53 |
+
|
| 54 |
+
uzunluk.sort()
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
def yzd(p):
|
| 58 |
+
return uzunluk[int(p * (len(uzunluk) - 1))] if uzunluk else 0
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
tekrar = sum(c - 1 for c in hashler.values() if c > 1)
|
| 62 |
+
print("=== CPT KULLIYAT DOKUMU ===")
|
| 63 |
+
print("kaynak : HuggingFaceFW/fineweb-2, tur_Latn, split=train (akis)")
|
| 64 |
+
print("dosya : %s" % SRC)
|
| 65 |
+
print("belge sayisi : %d" % n_belge)
|
| 66 |
+
print("toplam bayt : %.2f GB" % (n_bayt / 1e9))
|
| 67 |
+
print("belge uzunlugu : medyan %d B | %%10 %d | %%90 %d | %%99 %d B"
|
| 68 |
+
% (yzd(0.5), yzd(0.1), yzd(0.9), yzd(0.99)))
|
| 69 |
+
print()
|
| 70 |
+
print("dil dogrulamasi (islev sozcugu orani, ilk 2000 karakter):")
|
| 71 |
+
t = max(n_belge, 1)
|
| 72 |
+
print(" Turkce baskin : %d (%%%.2f)" % (tr_belge, 100.0 * tr_belge / t))
|
| 73 |
+
print(" Ingilizce baskin: %d (%%%.2f)" % (en_belge, 100.0 * en_belge / t))
|
| 74 |
+
print(" belirsiz : %d (%%%.2f)" % (belirsiz, 100.0 * belirsiz / t))
|
| 75 |
+
print()
|
| 76 |
+
print("yaklasik tekrar (ilk 300 karakter ozdes): %d belge (%%%.2f)"
|
| 77 |
+
% (tekrar, 100.0 * tekrar / t))
|
betikler/llama_cpp_surum.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
465e49b9cea78a68b9c244ffb48d0ee24a82873d
|
betikler/morfbench_olcek.py
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""TurkMorfBench — ZORUNLU SECIM olcumu (bicimden bagimsiz).
|
| 2 |
+
|
| 3 |
+
Uretimli olcumde stok Qwen3-32B'nin basarisizliklarinin cogu "hic cevap
|
| 4 |
+
vermemek" ya da Ingilizce akil yurutmeye kaymakti. Bu, morfoloji bilgisi
|
| 5 |
+
degil bicim uyumu olcer.
|
| 6 |
+
|
| 7 |
+
Burada model hicbir sey URETMEZ: ayni az-ornekli istem verilir, dogru
|
| 8 |
+
cekim ile fonolojik olarak YANLIS varyantlarinin log-olabilirligi
|
| 9 |
+
ogretmen-zorlamali hesaplanir, en yuksegi secilir. Susmak ya da dil
|
| 10 |
+
degistirmek secenek degildir.
|
| 11 |
+
|
| 12 |
+
Celdiriciler dilbilimsel: unlu uyumu (2'li a/e, 4'lu ı/i/u/ü) ve
|
| 13 |
+
unsuz benzesmesi (d/t) varyantlari. Yani model "sesi dogru olan"i
|
| 14 |
+
secmek zorunda.
|
| 15 |
+
"""
|
| 16 |
+
import os, json, re, gc, itertools, torch, torch.nn as nn
|
| 17 |
+
os.environ["HF_DATASETS_OFFLINE"] = "1"
|
| 18 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 19 |
+
|
| 20 |
+
MID = "/ari/users/ytanis/qwen3-32b"
|
| 21 |
+
# Olculecek checkpoint disaridan verilebilir: CPT ve SFT ayni betikle,
|
| 22 |
+
# ayni celdiricilerle, ayni protokolde olculsun diye.
|
| 23 |
+
CPT = os.environ.get("CK_DIR", "/ari/users/ytanis/erk32b-cpt")
|
| 24 |
+
ASAMA = "SFT" if CPT.rstrip("/").endswith("sft") else "CPT"
|
| 25 |
+
BENCH = "/ari/users/ytanis/turkmorfbench.json"
|
| 26 |
+
OLCEK = float(os.environ.get("OLCEK", "1.0"))
|
| 27 |
+
OUT = "/ari/users/ytanis/morfbench_zorunlu_%s_o%03d.json" % (os.path.basename(CPT.rstrip("/")), round(OLCEK * 100))
|
| 28 |
+
R, ALPHA = 256, 512
|
| 29 |
+
IKILI = "ae"
|
| 30 |
+
DORTLU = "ıiuü"
|
| 31 |
+
|
| 32 |
+
data = json.load(open(BENCH, encoding="utf-8"))
|
| 33 |
+
ORNEK = [("'kalem' kelimesinin çoğulu nedir?", "kalemler"),
|
| 34 |
+
("'defter' kelimesine -de/-da bulunma eki ekle.", "defterde"),
|
| 35 |
+
("'sandalye' kelimesini 'onun (3. tekil) ...' iyelik ekiyle çek.", "sandalyesi"),
|
| 36 |
+
("'bardak' kelimesini 'benim (1. tekil) ...' iyelik ekiyle çek.", "bardağım")]
|
| 37 |
+
ONEK = "".join("Soru: %s\nCevap: %s\n\n" % (s, c) for s, c in ORNEK)
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
def celdiriciler(kok, altin):
|
| 41 |
+
"""Altin cevabin EK kismini bulup fonolojik varyantlarini uret."""
|
| 42 |
+
# govde degismis olabilir (yumusama: kitap->kitab); ortak oneki bul
|
| 43 |
+
i = 0
|
| 44 |
+
while i < min(len(kok), len(altin)) and kok[i] == altin[i]:
|
| 45 |
+
i += 1
|
| 46 |
+
govde, ek = altin[:i], altin[i:]
|
| 47 |
+
if not ek:
|
| 48 |
+
return []
|
| 49 |
+
# ekteki her unluyu kendi sinifindaki alternatiflerle degistir
|
| 50 |
+
yerler = [(j, ch) for j, ch in enumerate(ek) if ch in IKILI + DORTLU]
|
| 51 |
+
if not yerler:
|
| 52 |
+
return []
|
| 53 |
+
secenekler = [list(IKILI if ch in IKILI else DORTLU) for _, ch in yerler]
|
| 54 |
+
adaylar = set()
|
| 55 |
+
for kombo in itertools.product(*secenekler):
|
| 56 |
+
y = list(ek)
|
| 57 |
+
for (j, _), v in zip(yerler, kombo):
|
| 58 |
+
y[j] = v
|
| 59 |
+
adaylar.add(govde + "".join(y))
|
| 60 |
+
# unsuz benzesmesi: ekin ilk harfi d/t ise digerini de dene
|
| 61 |
+
for a in list(adaylar):
|
| 62 |
+
e = a[len(govde):]
|
| 63 |
+
if e and e[0] in "dt":
|
| 64 |
+
adaylar.add(govde + ("t" if e[0] == "d" else "d") + e[1:])
|
| 65 |
+
# unsuz YUMUSAMASI celdiricisi: govde yumusamissa (kitap -> kitab...)
|
| 66 |
+
# yumusamamis hali de secenek olsun (kitapım) — kural boylece sinanir
|
| 67 |
+
if i < len(kok) and i < len(altin) and kok[i] != altin[i]:
|
| 68 |
+
adaylar.add(kok[:i + 1] + altin[i + 1:])
|
| 69 |
+
adaylar.discard(altin)
|
| 70 |
+
return sorted(adaylar)
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
tok = AutoTokenizer.from_pretrained(MID)
|
| 74 |
+
model = AutoModelForCausalLM.from_pretrained(MID, torch_dtype=torch.bfloat16,
|
| 75 |
+
device_map="auto").eval()
|
| 76 |
+
|
| 77 |
+
# secenek kumelerini bir kez kur
|
| 78 |
+
ITEMS = []
|
| 79 |
+
for x in data:
|
| 80 |
+
cel = celdiriciler(x["kok"], x["cevap"])
|
| 81 |
+
if not cel:
|
| 82 |
+
continue
|
| 83 |
+
if len(cel) > 7:
|
| 84 |
+
cel = cel[:7]
|
| 85 |
+
ITEMS.append({"x": x, "adaylar": [x["cevap"]] + cel})
|
| 86 |
+
print("zorunlu-secim uygulanabilen ornek: %d / %d | ortalama secenek: %.1f"
|
| 87 |
+
% (len(ITEMS), len(data), sum(len(i["adaylar"]) for i in ITEMS) / max(len(ITEMS), 1)), flush=True)
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
def skor(p_ids, aday_ids):
|
| 91 |
+
"""log P(aday | istem) — ogretmen zorlamali, uzunluga bolunmus."""
|
| 92 |
+
ids = torch.cat([p_ids, aday_ids], dim=1)
|
| 93 |
+
out = model(ids)
|
| 94 |
+
lp = torch.log_softmax(out.logits[0, :-1].float(), dim=-1)
|
| 95 |
+
hedef = ids[0, 1:]
|
| 96 |
+
n = aday_ids.shape[1]
|
| 97 |
+
return float(lp[-n:].gather(1, hedef[-n:].unsqueeze(1)).sum()) / n
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
def olc(etiket):
|
| 101 |
+
dogru = {"gercek": 0, "wug": 0}
|
| 102 |
+
top = {"gercek": 0, "wug": 0}
|
| 103 |
+
vec = [] # soru-bazli sonuc: eslestirilmis bootstrap icin sart
|
| 104 |
+
with torch.no_grad():
|
| 105 |
+
for it in ITEMS:
|
| 106 |
+
x = it["x"]
|
| 107 |
+
soru = x["soru"].replace(" Sadece kelimeyi yaz.", "")
|
| 108 |
+
p = ONEK + "Soru: %s\nCevap:" % soru
|
| 109 |
+
p_ids = tok(p, return_tensors="pt").input_ids.to(model.device)
|
| 110 |
+
en_iyi, en_skor = None, -1e9
|
| 111 |
+
for a in it["adaylar"]:
|
| 112 |
+
a_ids = tok(" " + a, add_special_tokens=False,
|
| 113 |
+
return_tensors="pt").input_ids.to(model.device)
|
| 114 |
+
s = skor(p_ids, a_ids)
|
| 115 |
+
if s > en_skor:
|
| 116 |
+
en_skor, en_iyi = s, a
|
| 117 |
+
ok = int(en_iyi == x["cevap"])
|
| 118 |
+
vec.append(ok)
|
| 119 |
+
top[x["tip"]] += 1
|
| 120 |
+
dogru[x["tip"]] += ok
|
| 121 |
+
g = 100.0 * dogru["gercek"] / max(top["gercek"], 1)
|
| 122 |
+
w = 100.0 * dogru["wug"] / max(top["wug"], 1)
|
| 123 |
+
t = 100.0 * (dogru["gercek"] + dogru["wug"]) / max(len(ITEMS), 1)
|
| 124 |
+
print("%-16s toplam %%%.2f | gercek %%%.2f (n=%d) | WUG %%%.2f (n=%d)"
|
| 125 |
+
% (etiket, t, g, top["gercek"], w, top["wug"]), flush=True)
|
| 126 |
+
return {"toplam": t, "gercek": g, "wug": w, "n_gercek": top["gercek"],
|
| 127 |
+
"n_wug": top["wug"], "vec": vec}
|
| 128 |
+
|
| 129 |
+
|
| 130 |
+
son = {"stok": olc("stok Qwen3-32B")}
|
| 131 |
+
|
| 132 |
+
|
| 133 |
+
class LoRA(nn.Module):
|
| 134 |
+
def __init__(self, base, r=R, alpha=ALPHA):
|
| 135 |
+
super().__init__(); self.base = base
|
| 136 |
+
d = base.weight.device
|
| 137 |
+
self.A = nn.Parameter(torch.zeros(r, base.in_features, device=d, dtype=torch.bfloat16))
|
| 138 |
+
self.B = nn.Parameter(torch.zeros(base.out_features, r, device=d, dtype=torch.bfloat16))
|
| 139 |
+
self.s = alpha / r
|
| 140 |
+
|
| 141 |
+
def forward(self, x):
|
| 142 |
+
if OLCEK == 0.0:
|
| 143 |
+
return self.base(x)
|
| 144 |
+
return self.base(x) + ((x @ self.A.t()) @ self.B.t()) * (self.s * OLCEK)
|
| 145 |
+
|
| 146 |
+
|
| 147 |
+
for layer in model.model.layers:
|
| 148 |
+
for mod, names in ((layer.self_attn, ["q_proj", "k_proj", "v_proj", "o_proj"]),
|
| 149 |
+
(layer.mlp, ["gate_proj", "up_proj", "down_proj"])):
|
| 150 |
+
for nm in names: setattr(mod, nm, LoRA(getattr(mod, nm)))
|
| 151 |
+
st = json.load(open(f"{CPT}/state.json"))
|
| 152 |
+
lsd = torch.load(f"{CPT}/lora_ck.pt", map_location="cpu", weights_only=True)
|
| 153 |
+
named = dict(model.named_parameters())
|
| 154 |
+
for k, v in lsd.items():
|
| 155 |
+
if k in named:
|
| 156 |
+
with torch.no_grad(): named[k].copy_(v.to(named[k].device))
|
| 157 |
+
del lsd; gc.collect()
|
| 158 |
+
model.eval()
|
| 159 |
+
print("\nLoRA yuklendi | adim %d\n" % st["step"], flush=True)
|
| 160 |
+
|
| 161 |
+
son["erk"] = olc("Erk-32B (ara)")
|
| 162 |
+
print("\n=== FARK (zorunlu secim) ===", flush=True)
|
| 163 |
+
for k in ("toplam", "gercek", "wug"):
|
| 164 |
+
print(" %-8s %+.2f puan" % (k, son["erk"][k] - son["stok"][k]), flush=True)
|
| 165 |
+
son["step"] = st["step"]
|
| 166 |
+
son["n_item"] = len(ITEMS)
|
| 167 |
+
son["tip"] = [it["x"]["tip"] for it in ITEMS]
|
| 168 |
+
|
| 169 |
+
# --- eslestirilmis bootstrap: fark gercek mi, gurultu mu?
|
| 170 |
+
import random
|
| 171 |
+
sv, ev = son["stok"]["vec"], son["erk"]["vec"]
|
| 172 |
+
tipler = son["tip"]
|
| 173 |
+
rnd = random.Random(31)
|
| 174 |
+
print("\n=== ESLESTIRILMIS BOOTSTRAP (%95 GA, 10.000 yeniden ornekleme) ===", flush=True)
|
| 175 |
+
for ad, sec in (("toplam", None), ("gercek", "gercek"), ("wug", "wug")):
|
| 176 |
+
idx = [i for i in range(len(sv)) if sec is None or tipler[i] == sec]
|
| 177 |
+
n = len(idx)
|
| 178 |
+
d = 100.0 * (sum(ev[i] for i in idx) - sum(sv[i] for i in idx)) / n
|
| 179 |
+
boot = []
|
| 180 |
+
for _ in range(10000):
|
| 181 |
+
pick = [idx[rnd.randrange(n)] for _ in range(n)]
|
| 182 |
+
boot.append(100.0 * (sum(ev[i] for i in pick) - sum(sv[i] for i in pick)) / n)
|
| 183 |
+
boot.sort()
|
| 184 |
+
lo, hi = boot[249], boot[9750]
|
| 185 |
+
print(" %-7s n=%3d fark %+5.2f [%+.2f, %+.2f] %s"
|
| 186 |
+
% (ad, n, d, lo, hi, "ANLAMLI" if (lo > 0 or hi < 0) else "anlamli degil"), flush=True)
|
| 187 |
+
|
| 188 |
+
json.dump(son, open(OUT, "w"), ensure_ascii=False)
|
| 189 |
+
print("BITTI", flush=True)
|
betikler/morfbench_olcek_v2.py
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""TurkMorfBench — ZORUNLU SECIM olcumu (bicimden bagimsiz).
|
| 2 |
+
|
| 3 |
+
Uretimli olcumde stok Qwen3-32B'nin basarisizliklarinin cogu "hic cevap
|
| 4 |
+
vermemek" ya da Ingilizce akil yurutmeye kaymakti. Bu, morfoloji bilgisi
|
| 5 |
+
degil bicim uyumu olcer.
|
| 6 |
+
|
| 7 |
+
Burada model hicbir sey URETMEZ: ayni az-ornekli istem verilir, dogru
|
| 8 |
+
cekim ile fonolojik olarak YANLIS varyantlarinin log-olabilirligi
|
| 9 |
+
ogretmen-zorlamali hesaplanir, en yuksegi secilir. Susmak ya da dil
|
| 10 |
+
degistirmek secenek degildir.
|
| 11 |
+
|
| 12 |
+
Celdiriciler dilbilimsel: unlu uyumu (2'li a/e, 4'lu ı/i/u/ü) ve
|
| 13 |
+
unsuz benzesmesi (d/t) varyantlari. Yani model "sesi dogru olan"i
|
| 14 |
+
secmek zorunda.
|
| 15 |
+
"""
|
| 16 |
+
import os, json, re, gc, itertools, torch, torch.nn as nn
|
| 17 |
+
os.environ["HF_DATASETS_OFFLINE"] = "1"
|
| 18 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 19 |
+
|
| 20 |
+
MID = "/ari/users/ytanis/qwen3-32b"
|
| 21 |
+
# Olculecek checkpoint disaridan verilebilir: CPT ve SFT ayni betikle,
|
| 22 |
+
# ayni celdiricilerle, ayni protokolde olculsun diye.
|
| 23 |
+
CPT = os.environ.get("CK_DIR", "/ari/users/ytanis/erk32b-cpt")
|
| 24 |
+
ASAMA = "SFT" if CPT.rstrip("/").endswith("sft") else "CPT"
|
| 25 |
+
BENCH = "/ari/users/ytanis/turkmorfbench_v2.json"
|
| 26 |
+
OLCEK = float(os.environ.get("OLCEK", "1.0"))
|
| 27 |
+
OUT = "/ari/users/ytanis/morfbench_v2_%s_o%03d.json" % (os.path.basename(CPT.rstrip("/")), round(OLCEK * 100))
|
| 28 |
+
R, ALPHA = 256, 512
|
| 29 |
+
IKILI = "ae"
|
| 30 |
+
DORTLU = "ıiuü"
|
| 31 |
+
|
| 32 |
+
data = json.load(open(BENCH, encoding="utf-8"))
|
| 33 |
+
# Az-ornekli govdeler KIYAS DISINDAN secilir. Onceki surum kalem/defter/bardak
|
| 34 |
+
# kullaniyordu; ucu de v2 gercek govdesi — model cevabi istemde goruyordu.
|
| 35 |
+
ORNEK = [("'tahta' kelimesinin çoğulu nedir?", "tahtalar"),
|
| 36 |
+
("'sepet' kelimesine -de/-da bulunma eki ekle.", "sepette"),
|
| 37 |
+
("'sandalye' kelimesini 'onun (3. tekil) ...' iyelik ekiyle çek.", "sandalyesi"),
|
| 38 |
+
("'kabak' kelimesini 'benim (1. tekil) ...' iyelik ekiyle çek.", "kabağım")]
|
| 39 |
+
ONEK = "".join("Soru: %s\nCevap: %s\n\n" % (s, c) for s, c in ORNEK)
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
def celdiriciler(kok, altin):
|
| 43 |
+
"""Altin cevabin EK kismini bulup fonolojik varyantlarini uret."""
|
| 44 |
+
# govde degismis olabilir (yumusama: kitap->kitab); ortak oneki bul
|
| 45 |
+
i = 0
|
| 46 |
+
while i < min(len(kok), len(altin)) and kok[i] == altin[i]:
|
| 47 |
+
i += 1
|
| 48 |
+
govde, ek = altin[:i], altin[i:]
|
| 49 |
+
if not ek:
|
| 50 |
+
return []
|
| 51 |
+
# ekteki her unluyu kendi sinifindaki alternatiflerle degistir
|
| 52 |
+
yerler = [(j, ch) for j, ch in enumerate(ek) if ch in IKILI + DORTLU]
|
| 53 |
+
if not yerler:
|
| 54 |
+
return []
|
| 55 |
+
secenekler = [list(IKILI if ch in IKILI else DORTLU) for _, ch in yerler]
|
| 56 |
+
adaylar = set()
|
| 57 |
+
for kombo in itertools.product(*secenekler):
|
| 58 |
+
y = list(ek)
|
| 59 |
+
for (j, _), v in zip(yerler, kombo):
|
| 60 |
+
y[j] = v
|
| 61 |
+
adaylar.add(govde + "".join(y))
|
| 62 |
+
# unsuz benzesmesi: ekin ilk harfi d/t ise digerini de dene
|
| 63 |
+
for a in list(adaylar):
|
| 64 |
+
e = a[len(govde):]
|
| 65 |
+
if e and e[0] in "dt":
|
| 66 |
+
adaylar.add(govde + ("t" if e[0] == "d" else "d") + e[1:])
|
| 67 |
+
# unsuz YUMUSAMASI celdiricisi: govde yumusamissa (kitap -> kitab...)
|
| 68 |
+
# yumusamamis hali de secenek olsun (kitapım) — kural boylece sinanir
|
| 69 |
+
if i < len(kok) and i < len(altin) and kok[i] != altin[i]:
|
| 70 |
+
adaylar.add(kok[:i + 1] + altin[i + 1:])
|
| 71 |
+
adaylar.discard(altin)
|
| 72 |
+
return sorted(adaylar)
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
tok = AutoTokenizer.from_pretrained(MID)
|
| 76 |
+
model = AutoModelForCausalLM.from_pretrained(MID, torch_dtype=torch.bfloat16,
|
| 77 |
+
device_map="auto").eval()
|
| 78 |
+
|
| 79 |
+
# secenek kumelerini bir kez kur
|
| 80 |
+
ITEMS = []
|
| 81 |
+
for x in data:
|
| 82 |
+
cel = celdiriciler(x["kok"], x["cevap"])
|
| 83 |
+
if not cel:
|
| 84 |
+
continue
|
| 85 |
+
if len(cel) > 7:
|
| 86 |
+
cel = cel[:7]
|
| 87 |
+
ITEMS.append({"x": x, "adaylar": [x["cevap"]] + cel})
|
| 88 |
+
print("zorunlu-secim uygulanabilen ornek: %d / %d | ortalama secenek: %.1f"
|
| 89 |
+
% (len(ITEMS), len(data), sum(len(i["adaylar"]) for i in ITEMS) / max(len(ITEMS), 1)), flush=True)
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
def skor(p_ids, aday_ids):
|
| 93 |
+
"""log P(aday | istem) — ogretmen zorlamali, uzunluga bolunmus."""
|
| 94 |
+
ids = torch.cat([p_ids, aday_ids], dim=1)
|
| 95 |
+
out = model(ids)
|
| 96 |
+
lp = torch.log_softmax(out.logits[0, :-1].float(), dim=-1)
|
| 97 |
+
hedef = ids[0, 1:]
|
| 98 |
+
n = aday_ids.shape[1]
|
| 99 |
+
return float(lp[-n:].gather(1, hedef[-n:].unsqueeze(1)).sum()) / n
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
def olc(etiket):
|
| 103 |
+
dogru = {"gercek": 0, "wug": 0}
|
| 104 |
+
top = {"gercek": 0, "wug": 0}
|
| 105 |
+
vec = [] # soru-bazli sonuc: eslestirilmis bootstrap icin sart
|
| 106 |
+
with torch.no_grad():
|
| 107 |
+
for it in ITEMS:
|
| 108 |
+
x = it["x"]
|
| 109 |
+
soru = x["soru"].replace(" Sadece kelimeyi yaz.", "")
|
| 110 |
+
p = ONEK + "Soru: %s\nCevap:" % soru
|
| 111 |
+
p_ids = tok(p, return_tensors="pt").input_ids.to(model.device)
|
| 112 |
+
en_iyi, en_skor = None, -1e9
|
| 113 |
+
for a in it["adaylar"]:
|
| 114 |
+
a_ids = tok(" " + a, add_special_tokens=False,
|
| 115 |
+
return_tensors="pt").input_ids.to(model.device)
|
| 116 |
+
s = skor(p_ids, a_ids)
|
| 117 |
+
if s > en_skor:
|
| 118 |
+
en_skor, en_iyi = s, a
|
| 119 |
+
ok = int(en_iyi == x["cevap"])
|
| 120 |
+
vec.append(ok)
|
| 121 |
+
top[x["tip"]] += 1
|
| 122 |
+
dogru[x["tip"]] += ok
|
| 123 |
+
g = 100.0 * dogru["gercek"] / max(top["gercek"], 1)
|
| 124 |
+
w = 100.0 * dogru["wug"] / max(top["wug"], 1)
|
| 125 |
+
t = 100.0 * (dogru["gercek"] + dogru["wug"]) / max(len(ITEMS), 1)
|
| 126 |
+
print("%-16s toplam %%%.2f | gercek %%%.2f (n=%d) | WUG %%%.2f (n=%d)"
|
| 127 |
+
% (etiket, t, g, top["gercek"], w, top["wug"]), flush=True)
|
| 128 |
+
return {"toplam": t, "gercek": g, "wug": w, "n_gercek": top["gercek"],
|
| 129 |
+
"n_wug": top["wug"], "vec": vec}
|
| 130 |
+
|
| 131 |
+
|
| 132 |
+
son = {"stok": olc("stok Qwen3-32B")}
|
| 133 |
+
|
| 134 |
+
|
| 135 |
+
class LoRA(nn.Module):
|
| 136 |
+
def __init__(self, base, r=R, alpha=ALPHA):
|
| 137 |
+
super().__init__(); self.base = base
|
| 138 |
+
d = base.weight.device
|
| 139 |
+
self.A = nn.Parameter(torch.zeros(r, base.in_features, device=d, dtype=torch.bfloat16))
|
| 140 |
+
self.B = nn.Parameter(torch.zeros(base.out_features, r, device=d, dtype=torch.bfloat16))
|
| 141 |
+
self.s = alpha / r
|
| 142 |
+
|
| 143 |
+
def forward(self, x):
|
| 144 |
+
if OLCEK == 0.0:
|
| 145 |
+
return self.base(x)
|
| 146 |
+
return self.base(x) + ((x @ self.A.t()) @ self.B.t()) * (self.s * OLCEK)
|
| 147 |
+
|
| 148 |
+
|
| 149 |
+
for layer in model.model.layers:
|
| 150 |
+
for mod, names in ((layer.self_attn, ["q_proj", "k_proj", "v_proj", "o_proj"]),
|
| 151 |
+
(layer.mlp, ["gate_proj", "up_proj", "down_proj"])):
|
| 152 |
+
for nm in names: setattr(mod, nm, LoRA(getattr(mod, nm)))
|
| 153 |
+
st = json.load(open(f"{CPT}/state.json"))
|
| 154 |
+
lsd = torch.load(f"{CPT}/lora_ck.pt", map_location="cpu", weights_only=True)
|
| 155 |
+
named = dict(model.named_parameters())
|
| 156 |
+
for k, v in lsd.items():
|
| 157 |
+
if k in named:
|
| 158 |
+
with torch.no_grad(): named[k].copy_(v.to(named[k].device))
|
| 159 |
+
del lsd; gc.collect()
|
| 160 |
+
model.eval()
|
| 161 |
+
print("\nLoRA yuklendi | adim %d\n" % st["step"], flush=True)
|
| 162 |
+
|
| 163 |
+
son["erk"] = olc("Erk-32B (ara)")
|
| 164 |
+
print("\n=== FARK (zorunlu secim) ===", flush=True)
|
| 165 |
+
for k in ("toplam", "gercek", "wug"):
|
| 166 |
+
print(" %-8s %+.2f puan" % (k, son["erk"][k] - son["stok"][k]), flush=True)
|
| 167 |
+
son["step"] = st["step"]
|
| 168 |
+
son["n_item"] = len(ITEMS)
|
| 169 |
+
son["tip"] = [it["x"]["tip"] for it in ITEMS]
|
| 170 |
+
|
| 171 |
+
# --- eslestirilmis bootstrap: fark gercek mi, gurultu mu?
|
| 172 |
+
import random
|
| 173 |
+
sv, ev = son["stok"]["vec"], son["erk"]["vec"]
|
| 174 |
+
tipler = son["tip"]
|
| 175 |
+
rnd = random.Random(31)
|
| 176 |
+
print("\n=== ESLESTIRILMIS BOOTSTRAP (%95 GA, 10.000 yeniden ornekleme) ===", flush=True)
|
| 177 |
+
for ad, sec in (("toplam", None), ("gercek", "gercek"), ("wug", "wug")):
|
| 178 |
+
idx = [i for i in range(len(sv)) if sec is None or tipler[i] == sec]
|
| 179 |
+
n = len(idx)
|
| 180 |
+
d = 100.0 * (sum(ev[i] for i in idx) - sum(sv[i] for i in idx)) / n
|
| 181 |
+
boot = []
|
| 182 |
+
for _ in range(10000):
|
| 183 |
+
pick = [idx[rnd.randrange(n)] for _ in range(n)]
|
| 184 |
+
boot.append(100.0 * (sum(ev[i] for i in pick) - sum(sv[i] for i in pick)) / n)
|
| 185 |
+
boot.sort()
|
| 186 |
+
lo, hi = boot[249], boot[9750]
|
| 187 |
+
print(" %-7s n=%3d fark %+5.2f [%+.2f, %+.2f] %s"
|
| 188 |
+
% (ad, n, d, lo, hi, "ANLAMLI" if (lo > 0 or hi < 0) else "anlamli degil"), flush=True)
|
| 189 |
+
|
| 190 |
+
json.dump(son, open(OUT, "w"), ensure_ascii=False)
|
| 191 |
+
print("BITTI", flush=True)
|
betikler/morfbench_zorunlu.py
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""TurkMorfBench — ZORUNLU SECIM olcumu (bicimden bagimsiz).
|
| 2 |
+
|
| 3 |
+
Uretimli olcumde stok Qwen3-32B'nin basarisizliklarinin cogu "hic cevap
|
| 4 |
+
vermemek" ya da Ingilizce akil yurutmeye kaymakti. Bu, morfoloji bilgisi
|
| 5 |
+
degil bicim uyumu olcer.
|
| 6 |
+
|
| 7 |
+
Burada model hicbir sey URETMEZ: ayni az-ornekli istem verilir, dogru
|
| 8 |
+
cekim ile fonolojik olarak YANLIS varyantlarinin log-olabilirligi
|
| 9 |
+
ogretmen-zorlamali hesaplanir, en yuksegi secilir. Susmak ya da dil
|
| 10 |
+
degistirmek secenek degildir.
|
| 11 |
+
|
| 12 |
+
Celdiriciler dilbilimsel: unlu uyumu (2'li a/e, 4'lu ı/i/u/ü) ve
|
| 13 |
+
unsuz benzesmesi (d/t) varyantlari. Yani model "sesi dogru olan"i
|
| 14 |
+
secmek zorunda.
|
| 15 |
+
"""
|
| 16 |
+
import os, json, re, gc, itertools, torch, torch.nn as nn
|
| 17 |
+
os.environ["HF_DATASETS_OFFLINE"] = "1"
|
| 18 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 19 |
+
|
| 20 |
+
MID = "/ari/users/ytanis/qwen3-32b"
|
| 21 |
+
# Olculecek checkpoint disaridan verilebilir: CPT ve SFT ayni betikle,
|
| 22 |
+
# ayni celdiricilerle, ayni protokolde olculsun diye.
|
| 23 |
+
CPT = os.environ.get("CK_DIR", "/ari/users/ytanis/erk32b-cpt")
|
| 24 |
+
ASAMA = "SFT" if CPT.rstrip("/").endswith("sft") else "CPT"
|
| 25 |
+
BENCH = "/ari/users/ytanis/turkmorfbench.json"
|
| 26 |
+
OUT = "/ari/users/ytanis/morfbench_zorunlu_%s.json" % ASAMA.lower()
|
| 27 |
+
R, ALPHA = 256, 512
|
| 28 |
+
IKILI = "ae"
|
| 29 |
+
DORTLU = "ıiuü"
|
| 30 |
+
|
| 31 |
+
data = json.load(open(BENCH, encoding="utf-8"))
|
| 32 |
+
ORNEK = [("'kalem' kelimesinin çoğulu nedir?", "kalemler"),
|
| 33 |
+
("'defter' kelimesine -de/-da bulunma eki ekle.", "defterde"),
|
| 34 |
+
("'sandalye' kelimesini 'onun (3. tekil) ...' iyelik ekiyle çek.", "sandalyesi"),
|
| 35 |
+
("'bardak' kelimesini 'benim (1. tekil) ...' iyelik ekiyle çek.", "bardağım")]
|
| 36 |
+
ONEK = "".join("Soru: %s\nCevap: %s\n\n" % (s, c) for s, c in ORNEK)
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def celdiriciler(kok, altin):
|
| 40 |
+
"""Altin cevabin EK kismini bulup fonolojik varyantlarini uret."""
|
| 41 |
+
# govde degismis olabilir (yumusama: kitap->kitab); ortak oneki bul
|
| 42 |
+
i = 0
|
| 43 |
+
while i < min(len(kok), len(altin)) and kok[i] == altin[i]:
|
| 44 |
+
i += 1
|
| 45 |
+
govde, ek = altin[:i], altin[i:]
|
| 46 |
+
if not ek:
|
| 47 |
+
return []
|
| 48 |
+
# ekteki her unluyu kendi sinifindaki alternatiflerle degistir
|
| 49 |
+
yerler = [(j, ch) for j, ch in enumerate(ek) if ch in IKILI + DORTLU]
|
| 50 |
+
if not yerler:
|
| 51 |
+
return []
|
| 52 |
+
secenekler = [list(IKILI if ch in IKILI else DORTLU) for _, ch in yerler]
|
| 53 |
+
adaylar = set()
|
| 54 |
+
for kombo in itertools.product(*secenekler):
|
| 55 |
+
y = list(ek)
|
| 56 |
+
for (j, _), v in zip(yerler, kombo):
|
| 57 |
+
y[j] = v
|
| 58 |
+
adaylar.add(govde + "".join(y))
|
| 59 |
+
# unsuz benzesmesi: ekin ilk harfi d/t ise digerini de dene
|
| 60 |
+
for a in list(adaylar):
|
| 61 |
+
e = a[len(govde):]
|
| 62 |
+
if e and e[0] in "dt":
|
| 63 |
+
adaylar.add(govde + ("t" if e[0] == "d" else "d") + e[1:])
|
| 64 |
+
# unsuz YUMUSAMASI celdiricisi: govde yumusamissa (kitap -> kitab...)
|
| 65 |
+
# yumusamamis hali de secenek olsun (kitapım) — kural boylece sinanir
|
| 66 |
+
if i < len(kok) and i < len(altin) and kok[i] != altin[i]:
|
| 67 |
+
adaylar.add(kok[:i + 1] + altin[i + 1:])
|
| 68 |
+
adaylar.discard(altin)
|
| 69 |
+
return sorted(adaylar)
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
tok = AutoTokenizer.from_pretrained(MID)
|
| 73 |
+
model = AutoModelForCausalLM.from_pretrained(MID, torch_dtype=torch.bfloat16,
|
| 74 |
+
device_map="auto").eval()
|
| 75 |
+
|
| 76 |
+
# secenek kumelerini bir kez kur
|
| 77 |
+
ITEMS = []
|
| 78 |
+
for x in data:
|
| 79 |
+
cel = celdiriciler(x["kok"], x["cevap"])
|
| 80 |
+
if not cel:
|
| 81 |
+
continue
|
| 82 |
+
if len(cel) > 7:
|
| 83 |
+
cel = cel[:7]
|
| 84 |
+
ITEMS.append({"x": x, "adaylar": [x["cevap"]] + cel})
|
| 85 |
+
print("zorunlu-secim uygulanabilen ornek: %d / %d | ortalama secenek: %.1f"
|
| 86 |
+
% (len(ITEMS), len(data), sum(len(i["adaylar"]) for i in ITEMS) / max(len(ITEMS), 1)), flush=True)
|
| 87 |
+
|
| 88 |
+
|
| 89 |
+
def skor(p_ids, aday_ids):
|
| 90 |
+
"""log P(aday | istem) — ogretmen zorlamali, uzunluga bolunmus."""
|
| 91 |
+
ids = torch.cat([p_ids, aday_ids], dim=1)
|
| 92 |
+
out = model(ids)
|
| 93 |
+
lp = torch.log_softmax(out.logits[0, :-1].float(), dim=-1)
|
| 94 |
+
hedef = ids[0, 1:]
|
| 95 |
+
n = aday_ids.shape[1]
|
| 96 |
+
return float(lp[-n:].gather(1, hedef[-n:].unsqueeze(1)).sum()) / n
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
def olc(etiket):
|
| 100 |
+
dogru = {"gercek": 0, "wug": 0}
|
| 101 |
+
top = {"gercek": 0, "wug": 0}
|
| 102 |
+
vec = [] # soru-bazli sonuc: eslestirilmis bootstrap icin sart
|
| 103 |
+
with torch.no_grad():
|
| 104 |
+
for it in ITEMS:
|
| 105 |
+
x = it["x"]
|
| 106 |
+
soru = x["soru"].replace(" Sadece kelimeyi yaz.", "")
|
| 107 |
+
p = ONEK + "Soru: %s\nCevap:" % soru
|
| 108 |
+
p_ids = tok(p, return_tensors="pt").input_ids.to(model.device)
|
| 109 |
+
en_iyi, en_skor = None, -1e9
|
| 110 |
+
for a in it["adaylar"]:
|
| 111 |
+
a_ids = tok(" " + a, add_special_tokens=False,
|
| 112 |
+
return_tensors="pt").input_ids.to(model.device)
|
| 113 |
+
s = skor(p_ids, a_ids)
|
| 114 |
+
if s > en_skor:
|
| 115 |
+
en_skor, en_iyi = s, a
|
| 116 |
+
ok = int(en_iyi == x["cevap"])
|
| 117 |
+
vec.append(ok)
|
| 118 |
+
top[x["tip"]] += 1
|
| 119 |
+
dogru[x["tip"]] += ok
|
| 120 |
+
g = 100.0 * dogru["gercek"] / max(top["gercek"], 1)
|
| 121 |
+
w = 100.0 * dogru["wug"] / max(top["wug"], 1)
|
| 122 |
+
t = 100.0 * (dogru["gercek"] + dogru["wug"]) / max(len(ITEMS), 1)
|
| 123 |
+
print("%-16s toplam %%%.2f | gercek %%%.2f (n=%d) | WUG %%%.2f (n=%d)"
|
| 124 |
+
% (etiket, t, g, top["gercek"], w, top["wug"]), flush=True)
|
| 125 |
+
return {"toplam": t, "gercek": g, "wug": w, "n_gercek": top["gercek"],
|
| 126 |
+
"n_wug": top["wug"], "vec": vec}
|
| 127 |
+
|
| 128 |
+
|
| 129 |
+
son = {"stok": olc("stok Qwen3-32B")}
|
| 130 |
+
|
| 131 |
+
|
| 132 |
+
class LoRA(nn.Module):
|
| 133 |
+
def __init__(self, base, r=R, alpha=ALPHA):
|
| 134 |
+
super().__init__(); self.base = base
|
| 135 |
+
d = base.weight.device
|
| 136 |
+
self.A = nn.Parameter(torch.zeros(r, base.in_features, device=d, dtype=torch.bfloat16))
|
| 137 |
+
self.B = nn.Parameter(torch.zeros(base.out_features, r, device=d, dtype=torch.bfloat16))
|
| 138 |
+
self.s = alpha / r
|
| 139 |
+
|
| 140 |
+
def forward(self, x):
|
| 141 |
+
return self.base(x) + ((x @ self.A.t()) @ self.B.t()) * self.s
|
| 142 |
+
|
| 143 |
+
|
| 144 |
+
for layer in model.model.layers:
|
| 145 |
+
for mod, names in ((layer.self_attn, ["q_proj", "k_proj", "v_proj", "o_proj"]),
|
| 146 |
+
(layer.mlp, ["gate_proj", "up_proj", "down_proj"])):
|
| 147 |
+
for nm in names: setattr(mod, nm, LoRA(getattr(mod, nm)))
|
| 148 |
+
st = json.load(open(f"{CPT}/state.json"))
|
| 149 |
+
lsd = torch.load(f"{CPT}/lora_ck.pt", map_location="cpu", weights_only=True)
|
| 150 |
+
named = dict(model.named_parameters())
|
| 151 |
+
for k, v in lsd.items():
|
| 152 |
+
if k in named:
|
| 153 |
+
with torch.no_grad(): named[k].copy_(v.to(named[k].device))
|
| 154 |
+
del lsd; gc.collect()
|
| 155 |
+
model.eval()
|
| 156 |
+
print("\nLoRA yuklendi | adim %d\n" % st["step"], flush=True)
|
| 157 |
+
|
| 158 |
+
son["erk"] = olc("Erk-32B (ara)")
|
| 159 |
+
print("\n=== FARK (zorunlu secim) ===", flush=True)
|
| 160 |
+
for k in ("toplam", "gercek", "wug"):
|
| 161 |
+
print(" %-8s %+.2f puan" % (k, son["erk"][k] - son["stok"][k]), flush=True)
|
| 162 |
+
son["step"] = st["step"]
|
| 163 |
+
son["n_item"] = len(ITEMS)
|
| 164 |
+
son["tip"] = [it["x"]["tip"] for it in ITEMS]
|
| 165 |
+
|
| 166 |
+
# --- eslestirilmis bootstrap: fark gercek mi, gurultu mu?
|
| 167 |
+
import random
|
| 168 |
+
sv, ev = son["stok"]["vec"], son["erk"]["vec"]
|
| 169 |
+
tipler = son["tip"]
|
| 170 |
+
rnd = random.Random(31)
|
| 171 |
+
print("\n=== ESLESTIRILMIS BOOTSTRAP (%95 GA, 10.000 yeniden ornekleme) ===", flush=True)
|
| 172 |
+
for ad, sec in (("toplam", None), ("gercek", "gercek"), ("wug", "wug")):
|
| 173 |
+
idx = [i for i in range(len(sv)) if sec is None or tipler[i] == sec]
|
| 174 |
+
n = len(idx)
|
| 175 |
+
d = 100.0 * (sum(ev[i] for i in idx) - sum(sv[i] for i in idx)) / n
|
| 176 |
+
boot = []
|
| 177 |
+
for _ in range(10000):
|
| 178 |
+
pick = [idx[rnd.randrange(n)] for _ in range(n)]
|
| 179 |
+
boot.append(100.0 * (sum(ev[i] for i in pick) - sum(sv[i] for i in pick)) / n)
|
| 180 |
+
boot.sort()
|
| 181 |
+
lo, hi = boot[249], boot[9750]
|
| 182 |
+
print(" %-7s n=%3d fark %+5.2f [%+.2f, %+.2f] %s"
|
| 183 |
+
% (ad, n, d, lo, hi, "ANLAMLI" if (lo > 0 or hi < 0) else "anlamli degil"), flush=True)
|
| 184 |
+
|
| 185 |
+
json.dump(son, open(OUT, "w"), ensure_ascii=False)
|
| 186 |
+
print("BITTI", flush=True)
|
betikler/olcek_birlesik.py
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""LoRA olcek taramasi — ince izgara, TOPLU uretim, guven araligiyla.
|
| 2 |
+
|
| 3 |
+
Kaba tarama (0.0/0.3/0.5/0.7/1.0) sunu gosterdi:
|
| 4 |
+
- kiyas kazanci 0.30'da doyuyor (0.50'de ayni, sonra dusuyor)
|
| 5 |
+
- sohbet 0.30'da tepe yapiyor, sonra dusuyor
|
| 6 |
+
Ama sohbet testi n=329 ve %95 belirsizlik +-5.4 puan; tepe gurultu olabilir.
|
| 7 |
+
|
| 8 |
+
Bu betik iki seyi duzeltir:
|
| 9 |
+
1) HIZ: uretim toplu yapilir (sol dolgulu yigin) — nokta basina 2.5 saat
|
| 10 |
+
yerine dakikalar. Kaba tarama bu yuzden zaman sinirina takilmisti.
|
| 11 |
+
2) KANIT: her ornegin sonucu kaydedilir, boylece noktalar arasi fark
|
| 12 |
+
eslestirilmis bootstrap ile sinanabilir.
|
| 13 |
+
"""
|
| 14 |
+
import os, json, re, gc, torch, torch.nn as nn
|
| 15 |
+
os.environ["HF_DATASETS_OFFLINE"] = "1"
|
| 16 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 17 |
+
from datasets import load_dataset
|
| 18 |
+
|
| 19 |
+
MID = "/ari/users/ytanis/erk32b-birlesik-080"
|
| 20 |
+
SFT = "/ari/users/ytanis/erk32b-sft2"
|
| 21 |
+
OUT = "/ari/users/ytanis/olcek_birlesik_080.json"
|
| 22 |
+
R, ALPHA = 256, 512
|
| 23 |
+
OLCEKLER = [0.0]
|
| 24 |
+
YIGIN = 16
|
| 25 |
+
MAKS_YENI = 640
|
| 26 |
+
|
| 27 |
+
morf = json.load(open("/ari/users/ytanis/turkmorfbench.json", encoding="utf-8"))
|
| 28 |
+
ds = load_dataset("AYueksel/TurkishMMLU", "All", split="test")
|
| 29 |
+
letters = "ABCDE"
|
| 30 |
+
probe = set(list(range(1, min(900, len(ds)), 6))[:150])
|
| 31 |
+
held = [i for i in range(min(900, len(ds))) if i not in probe]
|
| 32 |
+
KIR = set(json.load(open("/ari/users/ytanis/kirlilik_CPT.json"))["kirli_13"])
|
| 33 |
+
temiz = [i for i in held if i not in KIR]
|
| 34 |
+
|
| 35 |
+
tok = AutoTokenizer.from_pretrained(MID)
|
| 36 |
+
tok.padding_side = "left" # toplu uretim icin sart
|
| 37 |
+
if tok.pad_token is None:
|
| 38 |
+
tok.pad_token = tok.eos_token
|
| 39 |
+
lid = [tok(" " + c, add_special_tokens=False).input_ids[-1] for c in letters]
|
| 40 |
+
model = AutoModelForCausalLM.from_pretrained(MID, torch_dtype=torch.bfloat16,
|
| 41 |
+
device_map="auto").eval()
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
class LoRA(nn.Module):
|
| 45 |
+
OLCEK = 1.0
|
| 46 |
+
|
| 47 |
+
def __init__(self, base, r=R, alpha=ALPHA):
|
| 48 |
+
super().__init__(); self.base = base
|
| 49 |
+
d = base.weight.device
|
| 50 |
+
self.A = nn.Parameter(torch.zeros(r, base.in_features, device=d, dtype=torch.bfloat16))
|
| 51 |
+
self.B = nn.Parameter(torch.zeros(base.out_features, r, device=d, dtype=torch.bfloat16))
|
| 52 |
+
self.s = alpha / r
|
| 53 |
+
|
| 54 |
+
def forward(self, x):
|
| 55 |
+
if LoRA.OLCEK == 0.0:
|
| 56 |
+
return self.base(x)
|
| 57 |
+
return self.base(x) + ((x @ self.A.t()) @ self.B.t()) * (self.s * LoRA.OLCEK)
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
for layer in model.model.layers:
|
| 61 |
+
for mod, names in ((layer.self_attn, ["q_proj", "k_proj", "v_proj", "o_proj"]),
|
| 62 |
+
(layer.mlp, ["gate_proj", "up_proj", "down_proj"])):
|
| 63 |
+
for nm in names: setattr(mod, nm, LoRA(getattr(mod, nm)))
|
| 64 |
+
named = dict(model.named_parameters())
|
| 65 |
+
lsd = torch.load("%s/lora_ck.pt" % SFT, map_location="cpu", weights_only=True)
|
| 66 |
+
for k, v in lsd.items():
|
| 67 |
+
if k in named:
|
| 68 |
+
with torch.no_grad(): named[k].copy_(v.to(named[k].device))
|
| 69 |
+
del lsd; gc.collect(); model.eval()
|
| 70 |
+
print("hazir | yigin=%d | %d olcek" % (YIGIN, len(OLCEKLER)), flush=True)
|
| 71 |
+
|
| 72 |
+
ISTEM = ["<|im_start|>user\n%s<|im_end|>\n<|im_start|>assistant\n" % x["soru"] for x in morf]
|
| 73 |
+
ALTIN = [re.sub(r"[.,!?;:\"'()\[\]*`]", "", x["cevap"].strip().lower()) for x in morf]
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
def sil(s):
|
| 77 |
+
return re.sub(r"[.,!?;:\"'()\[\]*`]", "", s.strip().lower())
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
def sohbet_olc():
|
| 81 |
+
vec = []; kesik = 0
|
| 82 |
+
with torch.no_grad():
|
| 83 |
+
for b in range(0, len(ISTEM), YIGIN):
|
| 84 |
+
grup = ISTEM[b:b + YIGIN]
|
| 85 |
+
enc = tok(grup, return_tensors="pt", padding=True,
|
| 86 |
+
add_special_tokens=False).to(model.device)
|
| 87 |
+
out = model.generate(**enc, max_new_tokens=MAKS_YENI, do_sample=False,
|
| 88 |
+
pad_token_id=tok.pad_token_id)
|
| 89 |
+
for j in range(len(grup)):
|
| 90 |
+
u = out[j][enc.input_ids.shape[1]:]
|
| 91 |
+
raw = tok.decode(u, skip_special_tokens=True)
|
| 92 |
+
if len(u) >= MAKS_YENI: kesik += 1
|
| 93 |
+
c = raw.split("</think>", 1)[1] if "</think>" in raw else ("" if "<think>" in raw else raw)
|
| 94 |
+
g = ALTIN[b + j]
|
| 95 |
+
vec.append(int(bool(re.search(r"(?:^|\W)%s(?:\W|$)" % re.escape(g), sil(c)))))
|
| 96 |
+
return vec, kesik
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
def mmlu_olc():
|
| 100 |
+
vec = []
|
| 101 |
+
with torch.no_grad():
|
| 102 |
+
for i in temiz:
|
| 103 |
+
ex = ds[i]
|
| 104 |
+
try:
|
| 105 |
+
a = ex["answer"]
|
| 106 |
+
ans = int(a) if isinstance(a, int) else letters.index(str(a).strip())
|
| 107 |
+
except Exception:
|
| 108 |
+
vec.append(None); continue
|
| 109 |
+
ch = list(ex["choices"])[:5]; k = len(ch)
|
| 110 |
+
ch = ch[-1:] + ch[:-1]; ans = (ans + 1) % k
|
| 111 |
+
s = "Asagidaki coktan secmeli soruyu cevapla.\n\nSoru: " + str(ex["question"]) + "\n"
|
| 112 |
+
for j, c in enumerate(ch): s += "%s) %s\n" % (letters[j], c)
|
| 113 |
+
iid = tok(s + "Cevap:", return_tensors="pt", truncation=True,
|
| 114 |
+
max_length=1024).input_ids.to(model.device)
|
| 115 |
+
lg = model(iid).logits[0, -1]
|
| 116 |
+
vec.append(int(int(torch.stack([lg[t] for t in lid[:k]]).argmax()) == ans))
|
| 117 |
+
return vec
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
son = {}
|
| 121 |
+
print("\n%-8s %10s %13s %8s" % ("olcek", "sohbet", "TurkishMMLU", "kesik"), flush=True)
|
| 122 |
+
print("-" * 44, flush=True)
|
| 123 |
+
for o in OLCEKLER:
|
| 124 |
+
LoRA.OLCEK = o
|
| 125 |
+
sv, kesik = sohbet_olc()
|
| 126 |
+
mv = mmlu_olc()
|
| 127 |
+
sz = [x for x in sv if x is not None]; mz = [x for x in mv if x is not None]
|
| 128 |
+
son["%.2f" % o] = {"sohbet_vec": sv, "mmlu_vec": mv, "kesik": kesik,
|
| 129 |
+
"sohbet": 100.0 * sum(sz) / len(sz),
|
| 130 |
+
"mmlu": 100.0 * sum(mz) / len(mz)}
|
| 131 |
+
print("%-8.2f %9.2f%% %12.2f%% %8d"
|
| 132 |
+
% (o, son["%.2f" % o]["sohbet"], son["%.2f" % o]["mmlu"], kesik), flush=True)
|
| 133 |
+
json.dump(son, open(OUT, "w")) # her adimda kaydet (zaman siniri emniyeti)
|
| 134 |
+
|
| 135 |
+
print("\n-> %s" % OUT, flush=True)
|
| 136 |
+
print("BITTI", flush=True)
|
betikler/olcek_ince.py
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""LoRA olcek taramasi — ince izgara, TOPLU uretim, guven araligiyla.
|
| 2 |
+
|
| 3 |
+
Kaba tarama (0.0/0.3/0.5/0.7/1.0) sunu gosterdi:
|
| 4 |
+
- kiyas kazanci 0.30'da doyuyor (0.50'de ayni, sonra dusuyor)
|
| 5 |
+
- sohbet 0.30'da tepe yapiyor, sonra dusuyor
|
| 6 |
+
Ama sohbet testi n=329 ve %95 belirsizlik +-5.4 puan; tepe gurultu olabilir.
|
| 7 |
+
|
| 8 |
+
Bu betik iki seyi duzeltir:
|
| 9 |
+
1) HIZ: uretim toplu yapilir (sol dolgulu yigin) — nokta basina 2.5 saat
|
| 10 |
+
yerine dakikalar. Kaba tarama bu yuzden zaman sinirina takilmisti.
|
| 11 |
+
2) KANIT: her ornegin sonucu kaydedilir, boylece noktalar arasi fark
|
| 12 |
+
eslestirilmis bootstrap ile sinanabilir.
|
| 13 |
+
"""
|
| 14 |
+
import os, json, re, gc, torch, torch.nn as nn
|
| 15 |
+
os.environ["HF_DATASETS_OFFLINE"] = "1"
|
| 16 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 17 |
+
from datasets import load_dataset
|
| 18 |
+
|
| 19 |
+
MID = "/ari/users/ytanis/qwen3-32b"
|
| 20 |
+
SFT = "/ari/users/ytanis/erk32b-sft"
|
| 21 |
+
OUT = "/ari/users/ytanis/olcek_ince.json"
|
| 22 |
+
R, ALPHA = 256, 512
|
| 23 |
+
OLCEKLER = [0.0, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.50]
|
| 24 |
+
YIGIN = 16
|
| 25 |
+
MAKS_YENI = 640
|
| 26 |
+
|
| 27 |
+
morf = json.load(open("/ari/users/ytanis/turkmorfbench.json", encoding="utf-8"))
|
| 28 |
+
ds = load_dataset("AYueksel/TurkishMMLU", "All", split="test")
|
| 29 |
+
letters = "ABCDE"
|
| 30 |
+
probe = set(list(range(1, min(900, len(ds)), 6))[:150])
|
| 31 |
+
held = [i for i in range(min(900, len(ds))) if i not in probe]
|
| 32 |
+
KIR = set(json.load(open("/ari/users/ytanis/kirlilik_CPT.json"))["kirli_13"])
|
| 33 |
+
temiz = [i for i in held if i not in KIR]
|
| 34 |
+
|
| 35 |
+
tok = AutoTokenizer.from_pretrained(MID)
|
| 36 |
+
tok.padding_side = "left" # toplu uretim icin sart
|
| 37 |
+
if tok.pad_token is None:
|
| 38 |
+
tok.pad_token = tok.eos_token
|
| 39 |
+
lid = [tok(" " + c, add_special_tokens=False).input_ids[-1] for c in letters]
|
| 40 |
+
model = AutoModelForCausalLM.from_pretrained(MID, torch_dtype=torch.bfloat16,
|
| 41 |
+
device_map="auto").eval()
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
class LoRA(nn.Module):
|
| 45 |
+
OLCEK = 1.0
|
| 46 |
+
|
| 47 |
+
def __init__(self, base, r=R, alpha=ALPHA):
|
| 48 |
+
super().__init__(); self.base = base
|
| 49 |
+
d = base.weight.device
|
| 50 |
+
self.A = nn.Parameter(torch.zeros(r, base.in_features, device=d, dtype=torch.bfloat16))
|
| 51 |
+
self.B = nn.Parameter(torch.zeros(base.out_features, r, device=d, dtype=torch.bfloat16))
|
| 52 |
+
self.s = alpha / r
|
| 53 |
+
|
| 54 |
+
def forward(self, x):
|
| 55 |
+
if LoRA.OLCEK == 0.0:
|
| 56 |
+
return self.base(x)
|
| 57 |
+
return self.base(x) + ((x @ self.A.t()) @ self.B.t()) * (self.s * LoRA.OLCEK)
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
for layer in model.model.layers:
|
| 61 |
+
for mod, names in ((layer.self_attn, ["q_proj", "k_proj", "v_proj", "o_proj"]),
|
| 62 |
+
(layer.mlp, ["gate_proj", "up_proj", "down_proj"])):
|
| 63 |
+
for nm in names: setattr(mod, nm, LoRA(getattr(mod, nm)))
|
| 64 |
+
named = dict(model.named_parameters())
|
| 65 |
+
lsd = torch.load("%s/lora_ck.pt" % SFT, map_location="cpu", weights_only=True)
|
| 66 |
+
for k, v in lsd.items():
|
| 67 |
+
if k in named:
|
| 68 |
+
with torch.no_grad(): named[k].copy_(v.to(named[k].device))
|
| 69 |
+
del lsd; gc.collect(); model.eval()
|
| 70 |
+
print("hazir | yigin=%d | %d olcek" % (YIGIN, len(OLCEKLER)), flush=True)
|
| 71 |
+
|
| 72 |
+
ISTEM = ["<|im_start|>user\n%s<|im_end|>\n<|im_start|>assistant\n" % x["soru"] for x in morf]
|
| 73 |
+
ALTIN = [re.sub(r"[.,!?;:\"'()\[\]*`]", "", x["cevap"].strip().lower()) for x in morf]
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
def sil(s):
|
| 77 |
+
return re.sub(r"[.,!?;:\"'()\[\]*`]", "", s.strip().lower())
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
def sohbet_olc():
|
| 81 |
+
vec = []; kesik = 0
|
| 82 |
+
with torch.no_grad():
|
| 83 |
+
for b in range(0, len(ISTEM), YIGIN):
|
| 84 |
+
grup = ISTEM[b:b + YIGIN]
|
| 85 |
+
enc = tok(grup, return_tensors="pt", padding=True,
|
| 86 |
+
add_special_tokens=False).to(model.device)
|
| 87 |
+
out = model.generate(**enc, max_new_tokens=MAKS_YENI, do_sample=False,
|
| 88 |
+
pad_token_id=tok.pad_token_id)
|
| 89 |
+
for j in range(len(grup)):
|
| 90 |
+
u = out[j][enc.input_ids.shape[1]:]
|
| 91 |
+
raw = tok.decode(u, skip_special_tokens=True)
|
| 92 |
+
if len(u) >= MAKS_YENI: kesik += 1
|
| 93 |
+
c = raw.split("</think>", 1)[1] if "</think>" in raw else ("" if "<think>" in raw else raw)
|
| 94 |
+
g = ALTIN[b + j]
|
| 95 |
+
vec.append(int(bool(re.search(r"(?:^|\W)%s(?:\W|$)" % re.escape(g), sil(c)))))
|
| 96 |
+
return vec, kesik
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
def mmlu_olc():
|
| 100 |
+
vec = []
|
| 101 |
+
with torch.no_grad():
|
| 102 |
+
for i in temiz:
|
| 103 |
+
ex = ds[i]
|
| 104 |
+
try:
|
| 105 |
+
a = ex["answer"]
|
| 106 |
+
ans = int(a) if isinstance(a, int) else letters.index(str(a).strip())
|
| 107 |
+
except Exception:
|
| 108 |
+
vec.append(None); continue
|
| 109 |
+
ch = list(ex["choices"])[:5]; k = len(ch)
|
| 110 |
+
ch = ch[-1:] + ch[:-1]; ans = (ans + 1) % k
|
| 111 |
+
s = "Asagidaki coktan secmeli soruyu cevapla.\n\nSoru: " + str(ex["question"]) + "\n"
|
| 112 |
+
for j, c in enumerate(ch): s += "%s) %s\n" % (letters[j], c)
|
| 113 |
+
iid = tok(s + "Cevap:", return_tensors="pt", truncation=True,
|
| 114 |
+
max_length=1024).input_ids.to(model.device)
|
| 115 |
+
lg = model(iid).logits[0, -1]
|
| 116 |
+
vec.append(int(int(torch.stack([lg[t] for t in lid[:k]]).argmax()) == ans))
|
| 117 |
+
return vec
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
son = {}
|
| 121 |
+
print("\n%-8s %10s %13s %8s" % ("olcek", "sohbet", "TurkishMMLU", "kesik"), flush=True)
|
| 122 |
+
print("-" * 44, flush=True)
|
| 123 |
+
for o in OLCEKLER:
|
| 124 |
+
LoRA.OLCEK = o
|
| 125 |
+
sv, kesik = sohbet_olc()
|
| 126 |
+
mv = mmlu_olc()
|
| 127 |
+
sz = [x for x in sv if x is not None]; mz = [x for x in mv if x is not None]
|
| 128 |
+
son["%.2f" % o] = {"sohbet_vec": sv, "mmlu_vec": mv, "kesik": kesik,
|
| 129 |
+
"sohbet": 100.0 * sum(sz) / len(sz),
|
| 130 |
+
"mmlu": 100.0 * sum(mz) / len(mz)}
|
| 131 |
+
print("%-8.2f %9.2f%% %12.2f%% %8d"
|
| 132 |
+
% (o, son["%.2f" % o]["sohbet"], son["%.2f" % o]["mmlu"], kesik), flush=True)
|
| 133 |
+
json.dump(son, open(OUT, "w")) # her adimda kaydet (zaman siniri emniyeti)
|
| 134 |
+
|
| 135 |
+
print("\n-> %s" % OUT, flush=True)
|
| 136 |
+
print("BITTI", flush=True)
|
betikler/olcek_ince_sft2.py
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""LoRA olcek taramasi — ince izgara, TOPLU uretim, guven araligiyla.
|
| 2 |
+
|
| 3 |
+
Kaba tarama (0.0/0.3/0.5/0.7/1.0) sunu gosterdi:
|
| 4 |
+
- kiyas kazanci 0.30'da doyuyor (0.50'de ayni, sonra dusuyor)
|
| 5 |
+
- sohbet 0.30'da tepe yapiyor, sonra dusuyor
|
| 6 |
+
Ama sohbet testi n=329 ve %95 belirsizlik +-5.4 puan; tepe gurultu olabilir.
|
| 7 |
+
|
| 8 |
+
Bu betik iki seyi duzeltir:
|
| 9 |
+
1) HIZ: uretim toplu yapilir (sol dolgulu yigin) — nokta basina 2.5 saat
|
| 10 |
+
yerine dakikalar. Kaba tarama bu yuzden zaman sinirina takilmisti.
|
| 11 |
+
2) KANIT: her ornegin sonucu kaydedilir, boylece noktalar arasi fark
|
| 12 |
+
eslestirilmis bootstrap ile sinanabilir.
|
| 13 |
+
"""
|
| 14 |
+
import os, json, re, gc, torch, torch.nn as nn
|
| 15 |
+
os.environ["HF_DATASETS_OFFLINE"] = "1"
|
| 16 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 17 |
+
from datasets import load_dataset
|
| 18 |
+
|
| 19 |
+
MID = "/ari/users/ytanis/qwen3-32b"
|
| 20 |
+
SFT = "/ari/users/ytanis/erk32b-sft2"
|
| 21 |
+
OUT = "/ari/users/ytanis/olcek_ince_sft2.json"
|
| 22 |
+
R, ALPHA = 256, 512
|
| 23 |
+
OLCEKLER = [0.0, 0.30, 0.40, 0.50, 0.60, 0.80, 1.0]
|
| 24 |
+
YIGIN = 16
|
| 25 |
+
MAKS_YENI = 640
|
| 26 |
+
|
| 27 |
+
morf = json.load(open("/ari/users/ytanis/turkmorfbench.json", encoding="utf-8"))
|
| 28 |
+
ds = load_dataset("AYueksel/TurkishMMLU", "All", split="test")
|
| 29 |
+
letters = "ABCDE"
|
| 30 |
+
probe = set(list(range(1, min(900, len(ds)), 6))[:150])
|
| 31 |
+
held = [i for i in range(min(900, len(ds))) if i not in probe]
|
| 32 |
+
KIR = set(json.load(open("/ari/users/ytanis/kirlilik_CPT.json"))["kirli_13"])
|
| 33 |
+
temiz = [i for i in held if i not in KIR]
|
| 34 |
+
|
| 35 |
+
tok = AutoTokenizer.from_pretrained(MID)
|
| 36 |
+
tok.padding_side = "left" # toplu uretim icin sart
|
| 37 |
+
if tok.pad_token is None:
|
| 38 |
+
tok.pad_token = tok.eos_token
|
| 39 |
+
lid = [tok(" " + c, add_special_tokens=False).input_ids[-1] for c in letters]
|
| 40 |
+
model = AutoModelForCausalLM.from_pretrained(MID, torch_dtype=torch.bfloat16,
|
| 41 |
+
device_map="auto").eval()
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
class LoRA(nn.Module):
|
| 45 |
+
OLCEK = 1.0
|
| 46 |
+
|
| 47 |
+
def __init__(self, base, r=R, alpha=ALPHA):
|
| 48 |
+
super().__init__(); self.base = base
|
| 49 |
+
d = base.weight.device
|
| 50 |
+
self.A = nn.Parameter(torch.zeros(r, base.in_features, device=d, dtype=torch.bfloat16))
|
| 51 |
+
self.B = nn.Parameter(torch.zeros(base.out_features, r, device=d, dtype=torch.bfloat16))
|
| 52 |
+
self.s = alpha / r
|
| 53 |
+
|
| 54 |
+
def forward(self, x):
|
| 55 |
+
if LoRA.OLCEK == 0.0:
|
| 56 |
+
return self.base(x)
|
| 57 |
+
return self.base(x) + ((x @ self.A.t()) @ self.B.t()) * (self.s * LoRA.OLCEK)
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
for layer in model.model.layers:
|
| 61 |
+
for mod, names in ((layer.self_attn, ["q_proj", "k_proj", "v_proj", "o_proj"]),
|
| 62 |
+
(layer.mlp, ["gate_proj", "up_proj", "down_proj"])):
|
| 63 |
+
for nm in names: setattr(mod, nm, LoRA(getattr(mod, nm)))
|
| 64 |
+
named = dict(model.named_parameters())
|
| 65 |
+
lsd = torch.load("%s/lora_ck.pt" % SFT, map_location="cpu", weights_only=True)
|
| 66 |
+
for k, v in lsd.items():
|
| 67 |
+
if k in named:
|
| 68 |
+
with torch.no_grad(): named[k].copy_(v.to(named[k].device))
|
| 69 |
+
del lsd; gc.collect(); model.eval()
|
| 70 |
+
print("hazir | yigin=%d | %d olcek" % (YIGIN, len(OLCEKLER)), flush=True)
|
| 71 |
+
|
| 72 |
+
ISTEM = ["<|im_start|>user\n%s<|im_end|>\n<|im_start|>assistant\n" % x["soru"] for x in morf]
|
| 73 |
+
ALTIN = [re.sub(r"[.,!?;:\"'()\[\]*`]", "", x["cevap"].strip().lower()) for x in morf]
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
def sil(s):
|
| 77 |
+
return re.sub(r"[.,!?;:\"'()\[\]*`]", "", s.strip().lower())
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
def sohbet_olc():
|
| 81 |
+
vec = []; kesik = 0
|
| 82 |
+
with torch.no_grad():
|
| 83 |
+
for b in range(0, len(ISTEM), YIGIN):
|
| 84 |
+
grup = ISTEM[b:b + YIGIN]
|
| 85 |
+
enc = tok(grup, return_tensors="pt", padding=True,
|
| 86 |
+
add_special_tokens=False).to(model.device)
|
| 87 |
+
out = model.generate(**enc, max_new_tokens=MAKS_YENI, do_sample=False,
|
| 88 |
+
pad_token_id=tok.pad_token_id)
|
| 89 |
+
for j in range(len(grup)):
|
| 90 |
+
u = out[j][enc.input_ids.shape[1]:]
|
| 91 |
+
raw = tok.decode(u, skip_special_tokens=True)
|
| 92 |
+
if len(u) >= MAKS_YENI: kesik += 1
|
| 93 |
+
c = raw.split("</think>", 1)[1] if "</think>" in raw else ("" if "<think>" in raw else raw)
|
| 94 |
+
g = ALTIN[b + j]
|
| 95 |
+
vec.append(int(bool(re.search(r"(?:^|\W)%s(?:\W|$)" % re.escape(g), sil(c)))))
|
| 96 |
+
return vec, kesik
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
def mmlu_olc():
|
| 100 |
+
vec = []
|
| 101 |
+
with torch.no_grad():
|
| 102 |
+
for i in temiz:
|
| 103 |
+
ex = ds[i]
|
| 104 |
+
try:
|
| 105 |
+
a = ex["answer"]
|
| 106 |
+
ans = int(a) if isinstance(a, int) else letters.index(str(a).strip())
|
| 107 |
+
except Exception:
|
| 108 |
+
vec.append(None); continue
|
| 109 |
+
ch = list(ex["choices"])[:5]; k = len(ch)
|
| 110 |
+
ch = ch[-1:] + ch[:-1]; ans = (ans + 1) % k
|
| 111 |
+
s = "Asagidaki coktan secmeli soruyu cevapla.\n\nSoru: " + str(ex["question"]) + "\n"
|
| 112 |
+
for j, c in enumerate(ch): s += "%s) %s\n" % (letters[j], c)
|
| 113 |
+
iid = tok(s + "Cevap:", return_tensors="pt", truncation=True,
|
| 114 |
+
max_length=1024).input_ids.to(model.device)
|
| 115 |
+
lg = model(iid).logits[0, -1]
|
| 116 |
+
vec.append(int(int(torch.stack([lg[t] for t in lid[:k]]).argmax()) == ans))
|
| 117 |
+
return vec
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
son = {}
|
| 121 |
+
print("\n%-8s %10s %13s %8s" % ("olcek", "sohbet", "TurkishMMLU", "kesik"), flush=True)
|
| 122 |
+
print("-" * 44, flush=True)
|
| 123 |
+
for o in OLCEKLER:
|
| 124 |
+
LoRA.OLCEK = o
|
| 125 |
+
sv, kesik = sohbet_olc()
|
| 126 |
+
mv = mmlu_olc()
|
| 127 |
+
sz = [x for x in sv if x is not None]; mz = [x for x in mv if x is not None]
|
| 128 |
+
son["%.2f" % o] = {"sohbet_vec": sv, "mmlu_vec": mv, "kesik": kesik,
|
| 129 |
+
"sohbet": 100.0 * sum(sz) / len(sz),
|
| 130 |
+
"mmlu": 100.0 * sum(mz) / len(mz)}
|
| 131 |
+
print("%-8.2f %9.2f%% %12.2f%% %8d"
|
| 132 |
+
% (o, son["%.2f" % o]["sohbet"], son["%.2f" % o]["mmlu"], kesik), flush=True)
|
| 133 |
+
json.dump(son, open(OUT, "w")) # her adimda kaydet (zaman siniri emniyeti)
|
| 134 |
+
|
| 135 |
+
print("\n-> %s" % OUT, flush=True)
|
| 136 |
+
print("BITTI", flush=True)
|
betikler/olcek_ince_sft2_ince.py
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""LoRA olcek taramasi — ince izgara, TOPLU uretim, guven araligiyla.
|
| 2 |
+
|
| 3 |
+
Kaba tarama (0.0/0.3/0.5/0.7/1.0) sunu gosterdi:
|
| 4 |
+
- kiyas kazanci 0.30'da doyuyor (0.50'de ayni, sonra dusuyor)
|
| 5 |
+
- sohbet 0.30'da tepe yapiyor, sonra dusuyor
|
| 6 |
+
Ama sohbet testi n=329 ve %95 belirsizlik +-5.4 puan; tepe gurultu olabilir.
|
| 7 |
+
|
| 8 |
+
Bu betik iki seyi duzeltir:
|
| 9 |
+
1) HIZ: uretim toplu yapilir (sol dolgulu yigin) — nokta basina 2.5 saat
|
| 10 |
+
yerine dakikalar. Kaba tarama bu yuzden zaman sinirina takilmisti.
|
| 11 |
+
2) KANIT: her ornegin sonucu kaydedilir, boylece noktalar arasi fark
|
| 12 |
+
eslestirilmis bootstrap ile sinanabilir.
|
| 13 |
+
"""
|
| 14 |
+
import os, json, re, gc, torch, torch.nn as nn
|
| 15 |
+
os.environ["HF_DATASETS_OFFLINE"] = "1"
|
| 16 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 17 |
+
from datasets import load_dataset
|
| 18 |
+
|
| 19 |
+
MID = "/ari/users/ytanis/qwen3-32b"
|
| 20 |
+
SFT = "/ari/users/ytanis/erk32b-sft2"
|
| 21 |
+
OUT = "/ari/users/ytanis/olcek_ince_sft2_ince.json"
|
| 22 |
+
R, ALPHA = 256, 512
|
| 23 |
+
OLCEKLER = [0.70, 0.75, 0.85, 0.90, 0.95]
|
| 24 |
+
YIGIN = 16
|
| 25 |
+
MAKS_YENI = 640
|
| 26 |
+
|
| 27 |
+
morf = json.load(open("/ari/users/ytanis/turkmorfbench.json", encoding="utf-8"))
|
| 28 |
+
ds = load_dataset("AYueksel/TurkishMMLU", "All", split="test")
|
| 29 |
+
letters = "ABCDE"
|
| 30 |
+
probe = set(list(range(1, min(900, len(ds)), 6))[:150])
|
| 31 |
+
held = [i for i in range(min(900, len(ds))) if i not in probe]
|
| 32 |
+
KIR = set(json.load(open("/ari/users/ytanis/kirlilik_CPT.json"))["kirli_13"])
|
| 33 |
+
temiz = [i for i in held if i not in KIR]
|
| 34 |
+
|
| 35 |
+
tok = AutoTokenizer.from_pretrained(MID)
|
| 36 |
+
tok.padding_side = "left" # toplu uretim icin sart
|
| 37 |
+
if tok.pad_token is None:
|
| 38 |
+
tok.pad_token = tok.eos_token
|
| 39 |
+
lid = [tok(" " + c, add_special_tokens=False).input_ids[-1] for c in letters]
|
| 40 |
+
model = AutoModelForCausalLM.from_pretrained(MID, torch_dtype=torch.bfloat16,
|
| 41 |
+
device_map="auto").eval()
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
class LoRA(nn.Module):
|
| 45 |
+
OLCEK = 1.0
|
| 46 |
+
|
| 47 |
+
def __init__(self, base, r=R, alpha=ALPHA):
|
| 48 |
+
super().__init__(); self.base = base
|
| 49 |
+
d = base.weight.device
|
| 50 |
+
self.A = nn.Parameter(torch.zeros(r, base.in_features, device=d, dtype=torch.bfloat16))
|
| 51 |
+
self.B = nn.Parameter(torch.zeros(base.out_features, r, device=d, dtype=torch.bfloat16))
|
| 52 |
+
self.s = alpha / r
|
| 53 |
+
|
| 54 |
+
def forward(self, x):
|
| 55 |
+
if LoRA.OLCEK == 0.0:
|
| 56 |
+
return self.base(x)
|
| 57 |
+
return self.base(x) + ((x @ self.A.t()) @ self.B.t()) * (self.s * LoRA.OLCEK)
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
for layer in model.model.layers:
|
| 61 |
+
for mod, names in ((layer.self_attn, ["q_proj", "k_proj", "v_proj", "o_proj"]),
|
| 62 |
+
(layer.mlp, ["gate_proj", "up_proj", "down_proj"])):
|
| 63 |
+
for nm in names: setattr(mod, nm, LoRA(getattr(mod, nm)))
|
| 64 |
+
named = dict(model.named_parameters())
|
| 65 |
+
lsd = torch.load("%s/lora_ck.pt" % SFT, map_location="cpu", weights_only=True)
|
| 66 |
+
for k, v in lsd.items():
|
| 67 |
+
if k in named:
|
| 68 |
+
with torch.no_grad(): named[k].copy_(v.to(named[k].device))
|
| 69 |
+
del lsd; gc.collect(); model.eval()
|
| 70 |
+
print("hazir | yigin=%d | %d olcek" % (YIGIN, len(OLCEKLER)), flush=True)
|
| 71 |
+
|
| 72 |
+
ISTEM = ["<|im_start|>user\n%s<|im_end|>\n<|im_start|>assistant\n" % x["soru"] for x in morf]
|
| 73 |
+
ALTIN = [re.sub(r"[.,!?;:\"'()\[\]*`]", "", x["cevap"].strip().lower()) for x in morf]
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
def sil(s):
|
| 77 |
+
return re.sub(r"[.,!?;:\"'()\[\]*`]", "", s.strip().lower())
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
def sohbet_olc():
|
| 81 |
+
vec = []; kesik = 0
|
| 82 |
+
with torch.no_grad():
|
| 83 |
+
for b in range(0, len(ISTEM), YIGIN):
|
| 84 |
+
grup = ISTEM[b:b + YIGIN]
|
| 85 |
+
enc = tok(grup, return_tensors="pt", padding=True,
|
| 86 |
+
add_special_tokens=False).to(model.device)
|
| 87 |
+
out = model.generate(**enc, max_new_tokens=MAKS_YENI, do_sample=False,
|
| 88 |
+
pad_token_id=tok.pad_token_id)
|
| 89 |
+
for j in range(len(grup)):
|
| 90 |
+
u = out[j][enc.input_ids.shape[1]:]
|
| 91 |
+
raw = tok.decode(u, skip_special_tokens=True)
|
| 92 |
+
if len(u) >= MAKS_YENI: kesik += 1
|
| 93 |
+
c = raw.split("</think>", 1)[1] if "</think>" in raw else ("" if "<think>" in raw else raw)
|
| 94 |
+
g = ALTIN[b + j]
|
| 95 |
+
vec.append(int(bool(re.search(r"(?:^|\W)%s(?:\W|$)" % re.escape(g), sil(c)))))
|
| 96 |
+
return vec, kesik
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
def mmlu_olc():
|
| 100 |
+
vec = []
|
| 101 |
+
with torch.no_grad():
|
| 102 |
+
for i in temiz:
|
| 103 |
+
ex = ds[i]
|
| 104 |
+
try:
|
| 105 |
+
a = ex["answer"]
|
| 106 |
+
ans = int(a) if isinstance(a, int) else letters.index(str(a).strip())
|
| 107 |
+
except Exception:
|
| 108 |
+
vec.append(None); continue
|
| 109 |
+
ch = list(ex["choices"])[:5]; k = len(ch)
|
| 110 |
+
ch = ch[-1:] + ch[:-1]; ans = (ans + 1) % k
|
| 111 |
+
s = "Asagidaki coktan secmeli soruyu cevapla.\n\nSoru: " + str(ex["question"]) + "\n"
|
| 112 |
+
for j, c in enumerate(ch): s += "%s) %s\n" % (letters[j], c)
|
| 113 |
+
iid = tok(s + "Cevap:", return_tensors="pt", truncation=True,
|
| 114 |
+
max_length=1024).input_ids.to(model.device)
|
| 115 |
+
lg = model(iid).logits[0, -1]
|
| 116 |
+
vec.append(int(int(torch.stack([lg[t] for t in lid[:k]]).argmax()) == ans))
|
| 117 |
+
return vec
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
son = {}
|
| 121 |
+
print("\n%-8s %10s %13s %8s" % ("olcek", "sohbet", "TurkishMMLU", "kesik"), flush=True)
|
| 122 |
+
print("-" * 44, flush=True)
|
| 123 |
+
for o in OLCEKLER:
|
| 124 |
+
LoRA.OLCEK = o
|
| 125 |
+
sv, kesik = sohbet_olc()
|
| 126 |
+
mv = mmlu_olc()
|
| 127 |
+
sz = [x for x in sv if x is not None]; mz = [x for x in mv if x is not None]
|
| 128 |
+
son["%.2f" % o] = {"sohbet_vec": sv, "mmlu_vec": mv, "kesik": kesik,
|
| 129 |
+
"sohbet": 100.0 * sum(sz) / len(sz),
|
| 130 |
+
"mmlu": 100.0 * sum(mz) / len(mz)}
|
| 131 |
+
print("%-8.2f %9.2f%% %12.2f%% %8d"
|
| 132 |
+
% (o, son["%.2f" % o]["sohbet"], son["%.2f" % o]["mmlu"], kesik), flush=True)
|
| 133 |
+
json.dump(son, open(OUT, "w")) # her adimda kaydet (zaman siniri emniyeti)
|
| 134 |
+
|
| 135 |
+
print("\n-> %s" % OUT, flush=True)
|
| 136 |
+
print("BITTI", flush=True)
|
betikler/olcek_sistem_080.py
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""LoRA olcek taramasi — ince izgara, TOPLU uretim, guven araligiyla.
|
| 2 |
+
|
| 3 |
+
Kaba tarama (0.0/0.3/0.5/0.7/1.0) sunu gosterdi:
|
| 4 |
+
- kiyas kazanci 0.30'da doyuyor (0.50'de ayni, sonra dusuyor)
|
| 5 |
+
- sohbet 0.30'da tepe yapiyor, sonra dusuyor
|
| 6 |
+
Ama sohbet testi n=329 ve %95 belirsizlik +-5.4 puan; tepe gurultu olabilir.
|
| 7 |
+
|
| 8 |
+
Bu betik iki seyi duzeltir:
|
| 9 |
+
1) HIZ: uretim toplu yapilir (sol dolgulu yigin) — nokta basina 2.5 saat
|
| 10 |
+
yerine dakikalar. Kaba tarama bu yuzden zaman sinirina takilmisti.
|
| 11 |
+
2) KANIT: her ornegin sonucu kaydedilir, boylece noktalar arasi fark
|
| 12 |
+
eslestirilmis bootstrap ile sinanabilir.
|
| 13 |
+
"""
|
| 14 |
+
import os, json, re, gc, torch, torch.nn as nn
|
| 15 |
+
os.environ["HF_DATASETS_OFFLINE"] = "1"
|
| 16 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 17 |
+
from datasets import load_dataset
|
| 18 |
+
|
| 19 |
+
MID = "/ari/users/ytanis/qwen3-32b"
|
| 20 |
+
SFT = "/ari/users/ytanis/erk32b-sft2"
|
| 21 |
+
OUT = "/ari/users/ytanis/olcek_sistem_080.json"
|
| 22 |
+
R, ALPHA = 256, 512
|
| 23 |
+
OLCEKLER = [0.80]
|
| 24 |
+
YIGIN = 16
|
| 25 |
+
MAKS_YENI = 640
|
| 26 |
+
|
| 27 |
+
morf = json.load(open("/ari/users/ytanis/turkmorfbench.json", encoding="utf-8"))
|
| 28 |
+
ds = load_dataset("AYueksel/TurkishMMLU", "All", split="test")
|
| 29 |
+
letters = "ABCDE"
|
| 30 |
+
probe = set(list(range(1, min(900, len(ds)), 6))[:150])
|
| 31 |
+
held = [i for i in range(min(900, len(ds))) if i not in probe]
|
| 32 |
+
KIR = set(json.load(open("/ari/users/ytanis/kirlilik_CPT.json"))["kirli_13"])
|
| 33 |
+
temiz = [i for i in held if i not in KIR]
|
| 34 |
+
|
| 35 |
+
tok = AutoTokenizer.from_pretrained(MID)
|
| 36 |
+
tok.padding_side = "left" # toplu uretim icin sart
|
| 37 |
+
if tok.pad_token is None:
|
| 38 |
+
tok.pad_token = tok.eos_token
|
| 39 |
+
lid = [tok(" " + c, add_special_tokens=False).input_ids[-1] for c in letters]
|
| 40 |
+
model = AutoModelForCausalLM.from_pretrained(MID, torch_dtype=torch.bfloat16,
|
| 41 |
+
device_map="auto").eval()
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
class LoRA(nn.Module):
|
| 45 |
+
OLCEK = 1.0
|
| 46 |
+
|
| 47 |
+
def __init__(self, base, r=R, alpha=ALPHA):
|
| 48 |
+
super().__init__(); self.base = base
|
| 49 |
+
d = base.weight.device
|
| 50 |
+
self.A = nn.Parameter(torch.zeros(r, base.in_features, device=d, dtype=torch.bfloat16))
|
| 51 |
+
self.B = nn.Parameter(torch.zeros(base.out_features, r, device=d, dtype=torch.bfloat16))
|
| 52 |
+
self.s = alpha / r
|
| 53 |
+
|
| 54 |
+
def forward(self, x):
|
| 55 |
+
if LoRA.OLCEK == 0.0:
|
| 56 |
+
return self.base(x)
|
| 57 |
+
return self.base(x) + ((x @ self.A.t()) @ self.B.t()) * (self.s * LoRA.OLCEK)
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
for layer in model.model.layers:
|
| 61 |
+
for mod, names in ((layer.self_attn, ["q_proj", "k_proj", "v_proj", "o_proj"]),
|
| 62 |
+
(layer.mlp, ["gate_proj", "up_proj", "down_proj"])):
|
| 63 |
+
for nm in names: setattr(mod, nm, LoRA(getattr(mod, nm)))
|
| 64 |
+
named = dict(model.named_parameters())
|
| 65 |
+
lsd = torch.load("%s/lora_ck.pt" % SFT, map_location="cpu", weights_only=True)
|
| 66 |
+
for k, v in lsd.items():
|
| 67 |
+
if k in named:
|
| 68 |
+
with torch.no_grad(): named[k].copy_(v.to(named[k].device))
|
| 69 |
+
del lsd; gc.collect(); model.eval()
|
| 70 |
+
print("hazir | yigin=%d | %d olcek" % (YIGIN, len(OLCEKLER)), flush=True)
|
| 71 |
+
|
| 72 |
+
SISTEM = ("Sen Erk-32B'sin: eCloud Tech. tarafından, açık kaynaklı Qwen3-32B temel "
|
| 73 |
+
"modeli üzerine Türkçe devam-eğitimi ve talimat ayarıyla geliştirilmiş 32 "
|
| 74 |
+
"milyar parametreli bir Türkçe dil modelisin. Kimliğin, seni kimin "
|
| 75 |
+
"geliştirdiği ya da temel modelin sorulduğunda bunu açıkça söyle; başka "
|
| 76 |
+
"bir şirketin modeli olduğunu asla iddia etme.")
|
| 77 |
+
ISTEM = ["<|im_start|>system\n" + SISTEM + "<|im_end|>\n<|im_start|>user\n%s<|im_end|>\n<|im_start|>assistant\n" % x["soru"] for x in morf]
|
| 78 |
+
ALTIN = [re.sub(r"[.,!?;:\"'()\[\]*`]", "", x["cevap"].strip().lower()) for x in morf]
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
def sil(s):
|
| 82 |
+
return re.sub(r"[.,!?;:\"'()\[\]*`]", "", s.strip().lower())
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
def sohbet_olc():
|
| 86 |
+
vec = []; kesik = 0
|
| 87 |
+
with torch.no_grad():
|
| 88 |
+
for b in range(0, len(ISTEM), YIGIN):
|
| 89 |
+
grup = ISTEM[b:b + YIGIN]
|
| 90 |
+
enc = tok(grup, return_tensors="pt", padding=True,
|
| 91 |
+
add_special_tokens=False).to(model.device)
|
| 92 |
+
out = model.generate(**enc, max_new_tokens=MAKS_YENI, do_sample=False,
|
| 93 |
+
pad_token_id=tok.pad_token_id)
|
| 94 |
+
for j in range(len(grup)):
|
| 95 |
+
u = out[j][enc.input_ids.shape[1]:]
|
| 96 |
+
raw = tok.decode(u, skip_special_tokens=True)
|
| 97 |
+
if len(u) >= MAKS_YENI: kesik += 1
|
| 98 |
+
c = raw.split("</think>", 1)[1] if "</think>" in raw else ("" if "<think>" in raw else raw)
|
| 99 |
+
g = ALTIN[b + j]
|
| 100 |
+
vec.append(int(bool(re.search(r"(?:^|\W)%s(?:\W|$)" % re.escape(g), sil(c)))))
|
| 101 |
+
return vec, kesik
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
def mmlu_olc():
|
| 105 |
+
vec = []
|
| 106 |
+
with torch.no_grad():
|
| 107 |
+
for i in temiz:
|
| 108 |
+
ex = ds[i]
|
| 109 |
+
try:
|
| 110 |
+
a = ex["answer"]
|
| 111 |
+
ans = int(a) if isinstance(a, int) else letters.index(str(a).strip())
|
| 112 |
+
except Exception:
|
| 113 |
+
vec.append(None); continue
|
| 114 |
+
ch = list(ex["choices"])[:5]; k = len(ch)
|
| 115 |
+
ch = ch[-1:] + ch[:-1]; ans = (ans + 1) % k
|
| 116 |
+
s = "Asagidaki coktan secmeli soruyu cevapla.\n\nSoru: " + str(ex["question"]) + "\n"
|
| 117 |
+
for j, c in enumerate(ch): s += "%s) %s\n" % (letters[j], c)
|
| 118 |
+
iid = tok(s + "Cevap:", return_tensors="pt", truncation=True,
|
| 119 |
+
max_length=1024).input_ids.to(model.device)
|
| 120 |
+
lg = model(iid).logits[0, -1]
|
| 121 |
+
vec.append(int(int(torch.stack([lg[t] for t in lid[:k]]).argmax()) == ans))
|
| 122 |
+
return vec
|
| 123 |
+
|
| 124 |
+
|
| 125 |
+
son = {}
|
| 126 |
+
print("\n%-8s %10s %13s %8s" % ("olcek", "sohbet", "TurkishMMLU", "kesik"), flush=True)
|
| 127 |
+
print("-" * 44, flush=True)
|
| 128 |
+
for o in OLCEKLER:
|
| 129 |
+
LoRA.OLCEK = o
|
| 130 |
+
sv, kesik = sohbet_olc()
|
| 131 |
+
mv = mmlu_olc()
|
| 132 |
+
sz = [x for x in sv if x is not None]; mz = [x for x in mv if x is not None]
|
| 133 |
+
son["%.2f" % o] = {"sohbet_vec": sv, "mmlu_vec": mv, "kesik": kesik,
|
| 134 |
+
"sohbet": 100.0 * sum(sz) / len(sz),
|
| 135 |
+
"mmlu": 100.0 * sum(mz) / len(mz)}
|
| 136 |
+
print("%-8.2f %9.2f%% %12.2f%% %8d"
|
| 137 |
+
% (o, son["%.2f" % o]["sohbet"], son["%.2f" % o]["mmlu"], kesik), flush=True)
|
| 138 |
+
json.dump(son, open(OUT, "w")) # her adimda kaydet (zaman siniri emniyeti)
|
| 139 |
+
|
| 140 |
+
print("\n-> %s" % OUT, flush=True)
|
| 141 |
+
print("BITTI", flush=True)
|
betikler/olcek_sistem_v2.py
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""LoRA olcek taramasi — ince izgara, TOPLU uretim, guven araligiyla.
|
| 2 |
+
|
| 3 |
+
Kaba tarama (0.0/0.3/0.5/0.7/1.0) sunu gosterdi:
|
| 4 |
+
- kiyas kazanci 0.30'da doyuyor (0.50'de ayni, sonra dusuyor)
|
| 5 |
+
- sohbet 0.30'da tepe yapiyor, sonra dusuyor
|
| 6 |
+
Ama sohbet testi n=329 ve %95 belirsizlik +-5.4 puan; tepe gurultu olabilir.
|
| 7 |
+
|
| 8 |
+
Bu betik iki seyi duzeltir:
|
| 9 |
+
1) HIZ: uretim toplu yapilir (sol dolgulu yigin) — nokta basina 2.5 saat
|
| 10 |
+
yerine dakikalar. Kaba tarama bu yuzden zaman sinirina takilmisti.
|
| 11 |
+
2) KANIT: her ornegin sonucu kaydedilir, boylece noktalar arasi fark
|
| 12 |
+
eslestirilmis bootstrap ile sinanabilir.
|
| 13 |
+
"""
|
| 14 |
+
import os, json, re, gc, torch, torch.nn as nn
|
| 15 |
+
os.environ["HF_DATASETS_OFFLINE"] = "1"
|
| 16 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 17 |
+
from datasets import load_dataset
|
| 18 |
+
|
| 19 |
+
MID = "/ari/users/ytanis/qwen3-32b"
|
| 20 |
+
SFT = "/ari/users/ytanis/erk32b-sft2"
|
| 21 |
+
OUT = "/ari/users/ytanis/olcek_sistem_v2.json"
|
| 22 |
+
R, ALPHA = 256, 512
|
| 23 |
+
OLCEKLER = [0.80]
|
| 24 |
+
YIGIN = 16
|
| 25 |
+
MAKS_YENI = 640
|
| 26 |
+
|
| 27 |
+
morf = json.load(open("/ari/users/ytanis/turkmorfbench_v2.json", encoding="utf-8"))
|
| 28 |
+
ds = load_dataset("AYueksel/TurkishMMLU", "All", split="test")
|
| 29 |
+
letters = "ABCDE"
|
| 30 |
+
probe = set(list(range(1, min(900, len(ds)), 6))[:150])
|
| 31 |
+
held = [i for i in range(min(900, len(ds))) if i not in probe]
|
| 32 |
+
KIR = set(json.load(open("/ari/users/ytanis/kirlilik_CPT.json"))["kirli_13"])
|
| 33 |
+
temiz = [i for i in held if i not in KIR]
|
| 34 |
+
|
| 35 |
+
tok = AutoTokenizer.from_pretrained(MID)
|
| 36 |
+
tok.padding_side = "left" # toplu uretim icin sart
|
| 37 |
+
if tok.pad_token is None:
|
| 38 |
+
tok.pad_token = tok.eos_token
|
| 39 |
+
lid = [tok(" " + c, add_special_tokens=False).input_ids[-1] for c in letters]
|
| 40 |
+
model = AutoModelForCausalLM.from_pretrained(MID, torch_dtype=torch.bfloat16,
|
| 41 |
+
device_map="auto").eval()
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
class LoRA(nn.Module):
|
| 45 |
+
OLCEK = 1.0
|
| 46 |
+
|
| 47 |
+
def __init__(self, base, r=R, alpha=ALPHA):
|
| 48 |
+
super().__init__(); self.base = base
|
| 49 |
+
d = base.weight.device
|
| 50 |
+
self.A = nn.Parameter(torch.zeros(r, base.in_features, device=d, dtype=torch.bfloat16))
|
| 51 |
+
self.B = nn.Parameter(torch.zeros(base.out_features, r, device=d, dtype=torch.bfloat16))
|
| 52 |
+
self.s = alpha / r
|
| 53 |
+
|
| 54 |
+
def forward(self, x):
|
| 55 |
+
if LoRA.OLCEK == 0.0:
|
| 56 |
+
return self.base(x)
|
| 57 |
+
return self.base(x) + ((x @ self.A.t()) @ self.B.t()) * (self.s * LoRA.OLCEK)
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
for layer in model.model.layers:
|
| 61 |
+
for mod, names in ((layer.self_attn, ["q_proj", "k_proj", "v_proj", "o_proj"]),
|
| 62 |
+
(layer.mlp, ["gate_proj", "up_proj", "down_proj"])):
|
| 63 |
+
for nm in names: setattr(mod, nm, LoRA(getattr(mod, nm)))
|
| 64 |
+
named = dict(model.named_parameters())
|
| 65 |
+
lsd = torch.load("%s/lora_ck.pt" % SFT, map_location="cpu", weights_only=True)
|
| 66 |
+
for k, v in lsd.items():
|
| 67 |
+
if k in named:
|
| 68 |
+
with torch.no_grad(): named[k].copy_(v.to(named[k].device))
|
| 69 |
+
del lsd; gc.collect(); model.eval()
|
| 70 |
+
print("hazir | yigin=%d | %d olcek" % (YIGIN, len(OLCEKLER)), flush=True)
|
| 71 |
+
|
| 72 |
+
SISTEM = ("Sen Erk-32B'sin: eCloud Tech. tarafından, açık kaynaklı Qwen3-32B temel "
|
| 73 |
+
"modeli üzerine Türkçe devam-eğitimi ve talimat ayarıyla geliştirilmiş 32 "
|
| 74 |
+
"milyar parametreli bir Türkçe dil modelisin. Kimliğin, seni kimin "
|
| 75 |
+
"geliştirdiği ya da temel modelin sorulduğunda bunu açıkça söyle; başka "
|
| 76 |
+
"bir şirketin modeli olduğunu asla iddia etme.")
|
| 77 |
+
ISTEM = ["<|im_start|>system\n" + SISTEM + "<|im_end|>\n<|im_start|>user\n%s<|im_end|>\n<|im_start|>assistant\n" % x["soru"] for x in morf]
|
| 78 |
+
ALTIN = [re.sub(r"[.,!?;:\"'()\[\]*`]", "", x["cevap"].strip().lower()) for x in morf]
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
def sil(s):
|
| 82 |
+
return re.sub(r"[.,!?;:\"'()\[\]*`]", "", s.strip().lower())
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
def sohbet_olc():
|
| 86 |
+
vec = []; kesik = 0
|
| 87 |
+
with torch.no_grad():
|
| 88 |
+
for b in range(0, len(ISTEM), YIGIN):
|
| 89 |
+
grup = ISTEM[b:b + YIGIN]
|
| 90 |
+
enc = tok(grup, return_tensors="pt", padding=True,
|
| 91 |
+
add_special_tokens=False).to(model.device)
|
| 92 |
+
out = model.generate(**enc, max_new_tokens=MAKS_YENI, do_sample=False,
|
| 93 |
+
pad_token_id=tok.pad_token_id)
|
| 94 |
+
for j in range(len(grup)):
|
| 95 |
+
u = out[j][enc.input_ids.shape[1]:]
|
| 96 |
+
raw = tok.decode(u, skip_special_tokens=True)
|
| 97 |
+
if len(u) >= MAKS_YENI: kesik += 1
|
| 98 |
+
c = raw.split("</think>", 1)[1] if "</think>" in raw else ("" if "<think>" in raw else raw)
|
| 99 |
+
g = ALTIN[b + j]
|
| 100 |
+
vec.append(int(bool(re.search(r"(?:^|\W)%s(?:\W|$)" % re.escape(g), sil(c)))))
|
| 101 |
+
return vec, kesik
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
def mmlu_olc():
|
| 105 |
+
vec = []
|
| 106 |
+
with torch.no_grad():
|
| 107 |
+
for i in temiz:
|
| 108 |
+
ex = ds[i]
|
| 109 |
+
try:
|
| 110 |
+
a = ex["answer"]
|
| 111 |
+
ans = int(a) if isinstance(a, int) else letters.index(str(a).strip())
|
| 112 |
+
except Exception:
|
| 113 |
+
vec.append(None); continue
|
| 114 |
+
ch = list(ex["choices"])[:5]; k = len(ch)
|
| 115 |
+
ch = ch[-1:] + ch[:-1]; ans = (ans + 1) % k
|
| 116 |
+
s = "Asagidaki coktan secmeli soruyu cevapla.\n\nSoru: " + str(ex["question"]) + "\n"
|
| 117 |
+
for j, c in enumerate(ch): s += "%s) %s\n" % (letters[j], c)
|
| 118 |
+
iid = tok(s + "Cevap:", return_tensors="pt", truncation=True,
|
| 119 |
+
max_length=1024).input_ids.to(model.device)
|
| 120 |
+
lg = model(iid).logits[0, -1]
|
| 121 |
+
vec.append(int(int(torch.stack([lg[t] for t in lid[:k]]).argmax()) == ans))
|
| 122 |
+
return vec
|
| 123 |
+
|
| 124 |
+
|
| 125 |
+
son = {}
|
| 126 |
+
print("\n%-8s %10s %13s %8s" % ("olcek", "sohbet", "TurkishMMLU", "kesik"), flush=True)
|
| 127 |
+
print("-" * 44, flush=True)
|
| 128 |
+
for o in OLCEKLER:
|
| 129 |
+
LoRA.OLCEK = o
|
| 130 |
+
sv, kesik = sohbet_olc()
|
| 131 |
+
mv = mmlu_olc()
|
| 132 |
+
sz = [x for x in sv if x is not None]; mz = [x for x in mv if x is not None]
|
| 133 |
+
son["%.2f" % o] = {"sohbet_vec": sv, "mmlu_vec": mv, "kesik": kesik,
|
| 134 |
+
"sohbet": 100.0 * sum(sz) / len(sz),
|
| 135 |
+
"mmlu": 100.0 * sum(mz) / len(mz)}
|
| 136 |
+
print("%-8.2f %9.2f%% %12.2f%% %8d"
|
| 137 |
+
% (o, son["%.2f" % o]["sohbet"], son["%.2f" % o]["mmlu"], kesik), flush=True)
|
| 138 |
+
json.dump(son, open(OUT, "w")) # her adimda kaydet (zaman siniri emniyeti)
|
| 139 |
+
|
| 140 |
+
print("\n-> %s" % OUT, flush=True)
|
| 141 |
+
print("BITTI", flush=True)
|
betikler/olcek_taramasi.py
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Ek SFT sonrasi KIMLIK ve HATA BULMA — LoRA olcegi taramasi.
|
| 2 |
+
|
| 3 |
+
NEDEN: sinav olcek 0,40 ile kosuldu ve kimlik 1/5 cikti. Ama kimlik verisi
|
| 4 |
+
olcek 1,0 ile egitildi. Yeni ogretilen bir davranis 0,40 uygulanirken
|
| 5 |
+
seyrelmis olabilir — LoRA toplamsal: W = W_taban + olcek*(B@A)*(alpha/r).
|
| 6 |
+
|
| 7 |
+
Bu tarama iki sonuctan birini verecek:
|
| 8 |
+
a) kimlik yuksek olcekte duzeliyor -> sorun egitimde degil, isletme
|
| 9 |
+
noktasi secimindeydi; kiyas puani ile kimlik arasinda takas var demektir
|
| 10 |
+
ve takasi olcerek secebiliriz.
|
| 11 |
+
b) hicbir olcekte duzelmiyor -> tur gercekten basarisiz, kimlik verisi
|
| 12 |
+
ya karisima girmedi ya da 6.000 ornek 373.387 ornegin icinde eridi.
|
| 13 |
+
|
| 14 |
+
Kiyas puani BURADA olculmuyor (pahali). Once kimlik duzeliyor mu ona bakilir;
|
| 15 |
+
duzeliyorsa o olcekte kiyas puani ayrica olculur.
|
| 16 |
+
"""
|
| 17 |
+
import os, sys, json, re, gc, torch, torch.nn as nn
|
| 18 |
+
os.environ["HF_DATASETS_OFFLINE"] = "1"
|
| 19 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 20 |
+
|
| 21 |
+
MID = "/ari/users/ytanis/qwen3-32b"
|
| 22 |
+
CK = "/ari/users/ytanis/erk32b-sft2"
|
| 23 |
+
OUT = "/ari/users/ytanis/olcek_taramasi.json"
|
| 24 |
+
R, ALPHA = 256, 512
|
| 25 |
+
OLCEKLER = [0.0, 0.40, 0.60, 0.80, 1.00]
|
| 26 |
+
|
| 27 |
+
KIMLIK = [
|
| 28 |
+
("Seni kim gelistirdi?", ["eCloud"], ["Tongyi", "Alibaba"]),
|
| 29 |
+
("Kimsin?", ["Erk"], ["Tongyi", "Alibaba"]),
|
| 30 |
+
("Sen Qwen misin?", ["eCloud", "Erk"], []),
|
| 31 |
+
("Temel modelin ne?", ["Qwen"], []),
|
| 32 |
+
("Hangi sirket seni yapti?", ["eCloud"], ["Tongyi", "Alibaba"]),
|
| 33 |
+
]
|
| 34 |
+
HATA = [
|
| 35 |
+
("Kitapi masaya koydum.", True, "kitabi"), ("Kitabi masaya koydum.", False, None),
|
| 36 |
+
("Agaca baktim.", False, None), ("Cocukun oyuncagi kayboldu.", True, "cocugun"),
|
| 37 |
+
("Ekmeklar taze.", True, "ekmekler"), ("Ekmekler taze.", False, None),
|
| 38 |
+
("Gozlar yorgun.", True, "gozler"), ("Gozler yorgun.", False, None),
|
| 39 |
+
]
|
| 40 |
+
|
| 41 |
+
tok = AutoTokenizer.from_pretrained(MID)
|
| 42 |
+
model = AutoModelForCausalLM.from_pretrained(MID, torch_dtype=torch.bfloat16,
|
| 43 |
+
device_map="auto").eval()
|
| 44 |
+
|
| 45 |
+
class LoRA(nn.Module):
|
| 46 |
+
OLCEK = 0.0
|
| 47 |
+
def __init__(self, base):
|
| 48 |
+
super().__init__(); self.base = base
|
| 49 |
+
d = base.weight.device
|
| 50 |
+
self.A = nn.Parameter(torch.zeros(R, base.in_features, device=d, dtype=torch.bfloat16))
|
| 51 |
+
self.B = nn.Parameter(torch.zeros(base.out_features, R, device=d, dtype=torch.bfloat16))
|
| 52 |
+
self.s = ALPHA / R
|
| 53 |
+
def forward(self, x):
|
| 54 |
+
if LoRA.OLCEK == 0.0: return self.base(x)
|
| 55 |
+
return self.base(x) + ((x @ self.A.t()) @ self.B.t()) * (self.s * LoRA.OLCEK)
|
| 56 |
+
|
| 57 |
+
for layer in model.model.layers:
|
| 58 |
+
for mod, adlar in ((layer.self_attn, ["q_proj","k_proj","v_proj","o_proj"]),
|
| 59 |
+
(layer.mlp, ["gate_proj","up_proj","down_proj"])):
|
| 60 |
+
for nm in adlar: setattr(mod, nm, LoRA(getattr(mod, nm)))
|
| 61 |
+
named = dict(model.named_parameters())
|
| 62 |
+
|
| 63 |
+
lsd = torch.load("%s/lora_ck.pt" % CK, map_location="cpu", weights_only=True)
|
| 64 |
+
esles = 0
|
| 65 |
+
for k, v in lsd.items():
|
| 66 |
+
if k in named:
|
| 67 |
+
with torch.no_grad(): named[k].copy_(v.to(named[k].device))
|
| 68 |
+
esles += 1
|
| 69 |
+
print("LoRA anahtar eslesme: %d / %d (checkpoint icinde %d)" % (esles, len(named), len(lsd)), flush=True)
|
| 70 |
+
if esles == 0:
|
| 71 |
+
print("HATA: hicbir agirlik yuklenmedi — sinav anlamsiz olurdu, duruyorum", flush=True)
|
| 72 |
+
sys.exit(1)
|
| 73 |
+
del lsd; gc.collect(); model.eval()
|
| 74 |
+
|
| 75 |
+
def sor(istem, maks=300):
|
| 76 |
+
p = "<|im_start|>user\n%s /no_think<|im_end|>\n<|im_start|>assistant\n" % istem
|
| 77 |
+
ids = tok(p, return_tensors="pt", add_special_tokens=False).to(model.device)
|
| 78 |
+
with torch.no_grad():
|
| 79 |
+
o = model.generate(**ids, max_new_tokens=maks, do_sample=False, pad_token_id=tok.eos_token_id)
|
| 80 |
+
r = tok.decode(o[0][ids.input_ids.shape[1]:], skip_special_tokens=True)
|
| 81 |
+
return r.split("</think>",1)[1].strip() if "</think>" in r else r.strip()
|
| 82 |
+
|
| 83 |
+
son = {}
|
| 84 |
+
for ol in OLCEKLER:
|
| 85 |
+
LoRA.OLCEK = ol
|
| 86 |
+
print("\n" + "="*64 + "\n OLCEK %.2f%s\n" % (ol, " (= saf taban model)" if ol==0 else "") + "="*64, flush=True)
|
| 87 |
+
kd = 0
|
| 88 |
+
for soru, olmali, olmamali in KIMLIK:
|
| 89 |
+
c = sor(soru, 220)
|
| 90 |
+
iyi = any(x.lower() in c.lower() for x in olmali) and not any(x.lower() in c.lower() for x in olmamali)
|
| 91 |
+
kd += iyi
|
| 92 |
+
print(" %s %-26s %s" % ("+" if iyi else "-", soru, c[:78].replace("\n"," ")), flush=True)
|
| 93 |
+
hd = 0
|
| 94 |
+
for cumle, hatali, dogru in HATA:
|
| 95 |
+
c = sor("Su cumlede yazim hatasi var mi? Varsa duzelt:\n\n%s" % cumle, 260)
|
| 96 |
+
cl = c.lower()
|
| 97 |
+
dedi = bool(re.search(r"hata var|yanlis|duzelt|olmali|dogrusu", cl)) and \
|
| 98 |
+
not re.search(r"hata yok|dogru yazil|hata bulunmuyor", cl)
|
| 99 |
+
hd += (dedi and dogru.lower() in cl) if hatali else (not dedi)
|
| 100 |
+
print("\n KIMLIK %d/%d HATA BULMA %d/%d" % (kd, len(KIMLIK), hd, len(HATA)), flush=True)
|
| 101 |
+
son["%.2f" % ol] = {"kimlik": kd, "hata": hd}
|
| 102 |
+
|
| 103 |
+
print("\n" + "="*64)
|
| 104 |
+
print(" %-8s %-10s %s" % ("OLCEK", "KIMLIK", "HATA BULMA"))
|
| 105 |
+
for ol in OLCEKLER:
|
| 106 |
+
d = son["%.2f" % ol]
|
| 107 |
+
print(" %-8.2f %d/%-9d %d/%d" % (ol, d["kimlik"], len(KIMLIK), d["hata"], len(HATA)))
|
| 108 |
+
json.dump(son, open(OUT,"w"), ensure_ascii=False)
|
| 109 |
+
print("BITTI", flush=True)
|
betikler/olcek_v2.py
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""LoRA olcek taramasi — ince izgara, TOPLU uretim, guven araligiyla.
|
| 2 |
+
|
| 3 |
+
Kaba tarama (0.0/0.3/0.5/0.7/1.0) sunu gosterdi:
|
| 4 |
+
- kiyas kazanci 0.30'da doyuyor (0.50'de ayni, sonra dusuyor)
|
| 5 |
+
- sohbet 0.30'da tepe yapiyor, sonra dusuyor
|
| 6 |
+
Ama sohbet testi n=329 ve %95 belirsizlik +-5.4 puan; tepe gurultu olabilir.
|
| 7 |
+
|
| 8 |
+
Bu betik iki seyi duzeltir:
|
| 9 |
+
1) HIZ: uretim toplu yapilir (sol dolgulu yigin) — nokta basina 2.5 saat
|
| 10 |
+
yerine dakikalar. Kaba tarama bu yuzden zaman sinirina takilmisti.
|
| 11 |
+
2) KANIT: her ornegin sonucu kaydedilir, boylece noktalar arasi fark
|
| 12 |
+
eslestirilmis bootstrap ile sinanabilir.
|
| 13 |
+
"""
|
| 14 |
+
import os, json, re, gc, torch, torch.nn as nn
|
| 15 |
+
os.environ["HF_DATASETS_OFFLINE"] = "1"
|
| 16 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 17 |
+
from datasets import load_dataset
|
| 18 |
+
|
| 19 |
+
MID = "/ari/users/ytanis/qwen3-32b"
|
| 20 |
+
SFT = "/ari/users/ytanis/erk32b-sft2"
|
| 21 |
+
OUT = "/ari/users/ytanis/olcek_v2.json"
|
| 22 |
+
R, ALPHA = 256, 512
|
| 23 |
+
OLCEKLER = [0.0, 0.40, 0.75, 0.80, 0.85, 1.0]
|
| 24 |
+
YIGIN = 16
|
| 25 |
+
MAKS_YENI = 640
|
| 26 |
+
|
| 27 |
+
morf = json.load(open("/ari/users/ytanis/turkmorfbench_v2.json", encoding="utf-8"))
|
| 28 |
+
ds = load_dataset("AYueksel/TurkishMMLU", "All", split="test")
|
| 29 |
+
letters = "ABCDE"
|
| 30 |
+
probe = set(list(range(1, min(900, len(ds)), 6))[:150])
|
| 31 |
+
held = [i for i in range(min(900, len(ds))) if i not in probe]
|
| 32 |
+
KIR = set(json.load(open("/ari/users/ytanis/kirlilik_CPT.json"))["kirli_13"])
|
| 33 |
+
temiz = [i for i in held if i not in KIR]
|
| 34 |
+
|
| 35 |
+
tok = AutoTokenizer.from_pretrained(MID)
|
| 36 |
+
tok.padding_side = "left" # toplu uretim icin sart
|
| 37 |
+
if tok.pad_token is None:
|
| 38 |
+
tok.pad_token = tok.eos_token
|
| 39 |
+
lid = [tok(" " + c, add_special_tokens=False).input_ids[-1] for c in letters]
|
| 40 |
+
model = AutoModelForCausalLM.from_pretrained(MID, torch_dtype=torch.bfloat16,
|
| 41 |
+
device_map="auto").eval()
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
class LoRA(nn.Module):
|
| 45 |
+
OLCEK = 1.0
|
| 46 |
+
|
| 47 |
+
def __init__(self, base, r=R, alpha=ALPHA):
|
| 48 |
+
super().__init__(); self.base = base
|
| 49 |
+
d = base.weight.device
|
| 50 |
+
self.A = nn.Parameter(torch.zeros(r, base.in_features, device=d, dtype=torch.bfloat16))
|
| 51 |
+
self.B = nn.Parameter(torch.zeros(base.out_features, r, device=d, dtype=torch.bfloat16))
|
| 52 |
+
self.s = alpha / r
|
| 53 |
+
|
| 54 |
+
def forward(self, x):
|
| 55 |
+
if LoRA.OLCEK == 0.0:
|
| 56 |
+
return self.base(x)
|
| 57 |
+
return self.base(x) + ((x @ self.A.t()) @ self.B.t()) * (self.s * LoRA.OLCEK)
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
for layer in model.model.layers:
|
| 61 |
+
for mod, names in ((layer.self_attn, ["q_proj", "k_proj", "v_proj", "o_proj"]),
|
| 62 |
+
(layer.mlp, ["gate_proj", "up_proj", "down_proj"])):
|
| 63 |
+
for nm in names: setattr(mod, nm, LoRA(getattr(mod, nm)))
|
| 64 |
+
named = dict(model.named_parameters())
|
| 65 |
+
lsd = torch.load("%s/lora_ck.pt" % SFT, map_location="cpu", weights_only=True)
|
| 66 |
+
for k, v in lsd.items():
|
| 67 |
+
if k in named:
|
| 68 |
+
with torch.no_grad(): named[k].copy_(v.to(named[k].device))
|
| 69 |
+
del lsd; gc.collect(); model.eval()
|
| 70 |
+
print("hazir | yigin=%d | %d olcek" % (YIGIN, len(OLCEKLER)), flush=True)
|
| 71 |
+
|
| 72 |
+
ISTEM = ["<|im_start|>user\n%s<|im_end|>\n<|im_start|>assistant\n" % x["soru"] for x in morf]
|
| 73 |
+
ALTIN = [re.sub(r"[.,!?;:\"'()\[\]*`]", "", x["cevap"].strip().lower()) for x in morf]
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
def sil(s):
|
| 77 |
+
return re.sub(r"[.,!?;:\"'()\[\]*`]", "", s.strip().lower())
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
def sohbet_olc():
|
| 81 |
+
vec = []; kesik = 0
|
| 82 |
+
with torch.no_grad():
|
| 83 |
+
for b in range(0, len(ISTEM), YIGIN):
|
| 84 |
+
grup = ISTEM[b:b + YIGIN]
|
| 85 |
+
enc = tok(grup, return_tensors="pt", padding=True,
|
| 86 |
+
add_special_tokens=False).to(model.device)
|
| 87 |
+
out = model.generate(**enc, max_new_tokens=MAKS_YENI, do_sample=False,
|
| 88 |
+
pad_token_id=tok.pad_token_id)
|
| 89 |
+
for j in range(len(grup)):
|
| 90 |
+
u = out[j][enc.input_ids.shape[1]:]
|
| 91 |
+
raw = tok.decode(u, skip_special_tokens=True)
|
| 92 |
+
if len(u) >= MAKS_YENI: kesik += 1
|
| 93 |
+
c = raw.split("</think>", 1)[1] if "</think>" in raw else ("" if "<think>" in raw else raw)
|
| 94 |
+
g = ALTIN[b + j]
|
| 95 |
+
vec.append(int(bool(re.search(r"(?:^|\W)%s(?:\W|$)" % re.escape(g), sil(c)))))
|
| 96 |
+
return vec, kesik
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
def mmlu_olc():
|
| 100 |
+
vec = []
|
| 101 |
+
with torch.no_grad():
|
| 102 |
+
for i in temiz:
|
| 103 |
+
ex = ds[i]
|
| 104 |
+
try:
|
| 105 |
+
a = ex["answer"]
|
| 106 |
+
ans = int(a) if isinstance(a, int) else letters.index(str(a).strip())
|
| 107 |
+
except Exception:
|
| 108 |
+
vec.append(None); continue
|
| 109 |
+
ch = list(ex["choices"])[:5]; k = len(ch)
|
| 110 |
+
ch = ch[-1:] + ch[:-1]; ans = (ans + 1) % k
|
| 111 |
+
s = "Asagidaki coktan secmeli soruyu cevapla.\n\nSoru: " + str(ex["question"]) + "\n"
|
| 112 |
+
for j, c in enumerate(ch): s += "%s) %s\n" % (letters[j], c)
|
| 113 |
+
iid = tok(s + "Cevap:", return_tensors="pt", truncation=True,
|
| 114 |
+
max_length=1024).input_ids.to(model.device)
|
| 115 |
+
lg = model(iid).logits[0, -1]
|
| 116 |
+
vec.append(int(int(torch.stack([lg[t] for t in lid[:k]]).argmax()) == ans))
|
| 117 |
+
return vec
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
son = {}
|
| 121 |
+
print("\n%-8s %10s %13s %8s" % ("olcek", "sohbet", "TurkishMMLU", "kesik"), flush=True)
|
| 122 |
+
print("-" * 44, flush=True)
|
| 123 |
+
for o in OLCEKLER:
|
| 124 |
+
LoRA.OLCEK = o
|
| 125 |
+
sv, kesik = sohbet_olc()
|
| 126 |
+
mv = mmlu_olc()
|
| 127 |
+
sz = [x for x in sv if x is not None]; mz = [x for x in mv if x is not None]
|
| 128 |
+
son["%.2f" % o] = {"sohbet_vec": sv, "mmlu_vec": mv, "kesik": kesik,
|
| 129 |
+
"sohbet": 100.0 * sum(sz) / len(sz),
|
| 130 |
+
"mmlu": 100.0 * sum(mz) / len(mz)}
|
| 131 |
+
print("%-8.2f %9.2f%% %12.2f%% %8d"
|
| 132 |
+
% (o, son["%.2f" % o]["sohbet"], son["%.2f" % o]["mmlu"], kesik), flush=True)
|
| 133 |
+
json.dump(son, open(OUT, "w")) # her adimda kaydet (zaman siniri emniyeti)
|
| 134 |
+
|
| 135 |
+
print("\n-> %s" % OUT, flush=True)
|
| 136 |
+
print("BITTI", flush=True)
|
betikler/permutasyon_testi.py
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Sik-sirasi saglamlik testi: kazanc harf onyargisi mi, gercek bilgi mi?
|
| 2 |
+
|
| 3 |
+
Coktan secmeli log-olabilirlik olcumunun bilinen zayifligi, modelin
|
| 4 |
+
secenek HARFINE dair bir onsel ogrenmesidir. Siklar dondurulup dogru
|
| 5 |
+
cevabin harfi degistirildiginde sahte kazanc yok olur, gercek kazanc kalir.
|
| 6 |
+
|
| 7 |
+
Ayni GPU'da iki olcum: once stok taban, sonra ayni tabana LoRA takilarak
|
| 8 |
+
Erk-32B. Boylece taban bir kez yuklenir ve iki model birebir ayni kosulda
|
| 9 |
+
olculur.
|
| 10 |
+
|
| 11 |
+
Cikti: her model icin ORIJINAL ve DONDURULMUS sira altinda held-out 750.
|
| 12 |
+
"""
|
| 13 |
+
import os, json, torch, torch.nn as nn
|
| 14 |
+
os.environ["HF_DATASETS_OFFLINE"] = "1"
|
| 15 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 16 |
+
from datasets import load_dataset
|
| 17 |
+
|
| 18 |
+
MID = "/ari/users/ytanis/qwen3-32b"
|
| 19 |
+
CPT = "/ari/users/ytanis/erk32b-cpt"
|
| 20 |
+
OUT = "/ari/users/ytanis/permutasyon_testi.json"
|
| 21 |
+
R, ALPHA = 256, 512
|
| 22 |
+
|
| 23 |
+
tok = AutoTokenizer.from_pretrained(MID)
|
| 24 |
+
model = AutoModelForCausalLM.from_pretrained(MID, torch_dtype=torch.bfloat16,
|
| 25 |
+
device_map="auto").eval()
|
| 26 |
+
ds = load_dataset("AYueksel/TurkishMMLU", "All", split="test")
|
| 27 |
+
letters = "ABCDE"
|
| 28 |
+
lid = [tok(" " + c, add_special_tokens=False).input_ids[-1] for c in letters]
|
| 29 |
+
probe = set(list(range(1, min(900, len(ds)), 6))[:150])
|
| 30 |
+
held = [i for i in range(min(900, len(ds))) if i not in probe]
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def olc(kaydir):
|
| 34 |
+
"""kaydir=0: orijinal sira. kaydir=1: siklar bir basamak dondurulur."""
|
| 35 |
+
vec = []
|
| 36 |
+
with torch.no_grad():
|
| 37 |
+
for i in held:
|
| 38 |
+
ex = ds[i]
|
| 39 |
+
try:
|
| 40 |
+
a = ex["answer"]
|
| 41 |
+
ans = int(a) if isinstance(a, int) else letters.index(str(a).strip())
|
| 42 |
+
except Exception:
|
| 43 |
+
vec.append(None); continue
|
| 44 |
+
ch = list(ex["choices"])[:5]
|
| 45 |
+
k = len(ch)
|
| 46 |
+
if kaydir:
|
| 47 |
+
ch = ch[-kaydir:] + ch[:-kaydir] # dairesel kaydirma
|
| 48 |
+
ans = (ans + kaydir) % k # dogru cevap yeni yerine tasinir
|
| 49 |
+
s = "Asagidaki coktan secmeli soruyu cevapla.\n\nSoru: " + str(ex["question"]) + "\n"
|
| 50 |
+
for j, c in enumerate(ch):
|
| 51 |
+
s += "%s) %s\n" % (letters[j], c)
|
| 52 |
+
ids = tok(s + "Cevap:", return_tensors="pt", truncation=True,
|
| 53 |
+
max_length=1024).input_ids.to(model.device)
|
| 54 |
+
lg = model(ids).logits[0, -1]
|
| 55 |
+
vec.append(int(int(torch.stack([lg[t] for t in lid[:k]]).argmax()) == ans))
|
| 56 |
+
z = [x for x in vec if x is not None]
|
| 57 |
+
return 100.0 * sum(z) / len(z), vec
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
son = {}
|
| 61 |
+
for ad, kay in (("orijinal", 0), ("dondurulmus", 1)):
|
| 62 |
+
acc, vec = olc(kay)
|
| 63 |
+
son["stok_" + ad] = {"acc": acc, "vec": vec}
|
| 64 |
+
print("stok Qwen3-32B [%-12s] %%%.2f" % (ad, acc), flush=True)
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
class LoRA(nn.Module):
|
| 68 |
+
def __init__(self, base, r=R, alpha=ALPHA):
|
| 69 |
+
super().__init__(); self.base = base
|
| 70 |
+
d = base.weight.device
|
| 71 |
+
self.A = nn.Parameter(torch.zeros(r, base.in_features, device=d, dtype=torch.bfloat16))
|
| 72 |
+
self.B = nn.Parameter(torch.zeros(base.out_features, r, device=d, dtype=torch.bfloat16))
|
| 73 |
+
self.s = alpha / r
|
| 74 |
+
|
| 75 |
+
def forward(self, x):
|
| 76 |
+
return self.base(x) + ((x @ self.A.t()) @ self.B.t()) * self.s
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
for layer in model.model.layers:
|
| 80 |
+
for mod, names in ((layer.self_attn, ["q_proj", "k_proj", "v_proj", "o_proj"]),
|
| 81 |
+
(layer.mlp, ["gate_proj", "up_proj", "down_proj"])):
|
| 82 |
+
for nm in names: setattr(mod, nm, LoRA(getattr(mod, nm)))
|
| 83 |
+
st = json.load(open(f"{CPT}/state.json"))
|
| 84 |
+
lsd = torch.load(f"{CPT}/lora_ck.pt", map_location="cpu", weights_only=True)
|
| 85 |
+
named = dict(model.named_parameters()); n = 0
|
| 86 |
+
for k, v in lsd.items():
|
| 87 |
+
if k in named:
|
| 88 |
+
with torch.no_grad(): named[k].copy_(v.to(named[k].device))
|
| 89 |
+
n += 1
|
| 90 |
+
print("\nLoRA yuklendi: %d tensor | adim %d (%.2fB token)\n" % (n, st["step"], st["tokens"] / 1e9), flush=True)
|
| 91 |
+
model.eval()
|
| 92 |
+
|
| 93 |
+
for ad, kay in (("orijinal", 0), ("dondurulmus", 1)):
|
| 94 |
+
acc, vec = olc(kay)
|
| 95 |
+
son["erk_" + ad] = {"acc": acc, "vec": vec}
|
| 96 |
+
print("Erk-32B (ara) [%-12s] %%%.2f" % (ad, acc), flush=True)
|
| 97 |
+
|
| 98 |
+
print("\n=== KAZANC ===")
|
| 99 |
+
for ad in ("orijinal", "dondurulmus"):
|
| 100 |
+
d = son["erk_" + ad]["acc"] - son["stok_" + ad]["acc"]
|
| 101 |
+
print(" %-12s fark: %+.2f puan" % (ad, d))
|
| 102 |
+
son["step"] = st["step"]
|
| 103 |
+
json.dump(son, open(OUT, "w"))
|
| 104 |
+
print("-> %s" % OUT)
|
| 105 |
+
print("BITTI", flush=True)
|
betikler/sablon_yama.py
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Sohbet sablonuna VARSAYILAN kimlik sistem istemi ekle.
|
| 2 |
+
|
| 3 |
+
NEDEN: kimlik agirliklarda 0,80 olceginde 12/30, sistem istemiyle 30/30. Istemi
|
| 4 |
+
kullaniciya birakirsak GGUF/ollama/transformers kullanicilarinin cogu koymaz ve
|
| 5 |
+
model taban modelin kimligini soyler. Sablon degisikligi bunu her dagitim
|
| 6 |
+
yolunda cozer: kullanici sistem mesaji vermezse varsayilan girer, verirse
|
| 7 |
+
kullanicininki gecerli olur (varsayilan EKLENMEZ, ustune yazilmaz).
|
| 8 |
+
|
| 9 |
+
Kullanim: python sablon_yama.py <model_dizini>
|
| 10 |
+
Birlestirme her tekrarlandiginda YENIDEN kosulmali: birlestir.py sablonu tabandan
|
| 11 |
+
kopyalar. Betik kendi degisikligini taniyip ikinci kez uygulamaz.
|
| 12 |
+
"""
|
| 13 |
+
import os, sys, json
|
| 14 |
+
|
| 15 |
+
DIZIN = sys.argv[1] if len(sys.argv) > 1 else "/ari/users/ytanis/erk32b-birlesik-080"
|
| 16 |
+
SISTEM = ("Sen Erk-32B'sin: eCloud Tech. tarafından, açık kaynaklı Qwen3-32B temel "
|
| 17 |
+
"modeli üzerine Türkçe devam-eğitimi ve talimat ayarıyla geliştirilmiş 32 "
|
| 18 |
+
"milyar parametreli bir Türkçe dil modelisin. Kimliğin, seni kimin "
|
| 19 |
+
"geliştirdiği ya da temel modelin sorulduğunda bunu açıkça söyle; başka "
|
| 20 |
+
"bir şirketin modeli olduğunu asla iddia etme.")
|
| 21 |
+
ISARET = "{#- erk-varsayilan-sistem -#}"
|
| 22 |
+
|
| 23 |
+
yol = os.path.join(DIZIN, "chat_template.jinja")
|
| 24 |
+
s = open(yol, encoding="utf-8").read()
|
| 25 |
+
if ISARET in s:
|
| 26 |
+
print("sablon zaten yamali, dokunulmadi"); sys.exit(0)
|
| 27 |
+
open(yol + ".taban", "w", encoding="utf-8").write(s)
|
| 28 |
+
|
| 29 |
+
# Jinja icinde tek tirnakli dize: istemde tek tirnak var ("Erk-32B'sin") -> kacir
|
| 30 |
+
j = SISTEM.replace("\\", "\\\\").replace("'", "\\'")
|
| 31 |
+
|
| 32 |
+
# (a) araclarla cagri dali: sistem mesaji yoksa varsayilani "# Tools"tan once koy
|
| 33 |
+
eski_a = (" {%- if messages[0].role == 'system' %}\n"
|
| 34 |
+
" {{- messages[0].content + '\\n\\n' }}\n"
|
| 35 |
+
" {%- endif %}\n")
|
| 36 |
+
yeni_a = (" {%- if messages[0].role == 'system' %}\n"
|
| 37 |
+
" {{- messages[0].content + '\\n\\n' }}\n"
|
| 38 |
+
" {%- else %}\n"
|
| 39 |
+
" {{- '" + j + "' + '\\n\\n' }}\n"
|
| 40 |
+
" {%- endif %}\n")
|
| 41 |
+
# (b) normal dal
|
| 42 |
+
eski_b = (" {%- if messages[0].role == 'system' %}\n"
|
| 43 |
+
" {{- '<|im_start|>system\\n' + messages[0].content + '<|im_end|>\\n' }}\n"
|
| 44 |
+
" {%- endif %}\n")
|
| 45 |
+
yeni_b = (" {%- if messages[0].role == 'system' %}\n"
|
| 46 |
+
" {{- '<|im_start|>system\\n' + messages[0].content + '<|im_end|>\\n' }}\n"
|
| 47 |
+
" {%- else %}\n"
|
| 48 |
+
" {{- '<|im_start|>system\\n' + '" + j + "' + '<|im_end|>\\n' }}\n"
|
| 49 |
+
" {%- endif %}\n")
|
| 50 |
+
for e, y, ad in ((eski_a, yeni_a, "arac dali"), (eski_b, yeni_b, "normal dal")):
|
| 51 |
+
assert s.count(e) == 1, "%s: hedef blok tam bir kez bulunmali (bulunan: %d)" % (ad, s.count(e))
|
| 52 |
+
s = s.replace(e, y)
|
| 53 |
+
s = ISARET + "\n" + s
|
| 54 |
+
open(yol, "w", encoding="utf-8").write(s)
|
| 55 |
+
|
| 56 |
+
# tokenizer_config.json icindeki kopya da guncellenmeli (transformers oradan okur)
|
| 57 |
+
tc = os.path.join(DIZIN, "tokenizer_config.json")
|
| 58 |
+
if os.path.exists(tc):
|
| 59 |
+
d = json.load(open(tc, encoding="utf-8"))
|
| 60 |
+
if "chat_template" in d:
|
| 61 |
+
d["chat_template"] = s
|
| 62 |
+
json.dump(d, open(tc, "w", encoding="utf-8"), ensure_ascii=False, indent=2)
|
| 63 |
+
print("tokenizer_config.json chat_template guncellendi")
|
| 64 |
+
|
| 65 |
+
# dogrulama: sistem mesaji yoksa varsayilan girer, varsa girmez
|
| 66 |
+
from transformers import AutoTokenizer
|
| 67 |
+
tok = AutoTokenizer.from_pretrained(DIZIN)
|
| 68 |
+
a = tok.apply_chat_template([{"role": "user", "content": "Kimsin?"}], tokenize=False, add_generation_prompt=True)
|
| 69 |
+
b = tok.apply_chat_template([{"role": "system", "content": "Sen bir çevirmensin."},
|
| 70 |
+
{"role": "user", "content": "Kimsin?"}], tokenize=False, add_generation_prompt=True)
|
| 71 |
+
assert "Erk-32B" in a and a.count("<|im_start|>system") == 1, "varsayilan girmedi"
|
| 72 |
+
assert "Erk-32B" not in b and "çevirmensin" in b and b.count("<|im_start|>system") == 1, "kullanici istemi ezildi"
|
| 73 |
+
print("sablon yamalandi ve dogrulandi: varsayilan girer / kullanici istemi korunur")
|
betikler/sft32b_ek.py
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Erk-32B SFT — FSDP LoRA, CPT checkpoint'i uzerine, kaldigi yerden devam.
|
| 2 |
+
|
| 3 |
+
CPT iskeletinin aynisi; farklar:
|
| 4 |
+
- veri paketlenmis (ids, labels); kayip yalnizca asistan iceriginde
|
| 5 |
+
- LR dusuk (2e-5) ve sonda ~0'a iner
|
| 6 |
+
- ilk baslatmada LoRA agirliklari CPT checkpoint'inden ISIKLENIR
|
| 7 |
+
(OUT_SFT bos ise); sonraki parcalar kendi checkpoint'inden devam eder
|
| 8 |
+
|
| 9 |
+
Kullanim: torchrun --nproc_per_node=4 sft32b_train.py <sure_dk>
|
| 10 |
+
"""
|
| 11 |
+
import os, sys, time, math, json, functools, torch, torch.nn as nn, torch.distributed as dist
|
| 12 |
+
from torch.distributed.fsdp import FullyShardedDataParallel as FSDP, MixedPrecision, StateDictType
|
| 13 |
+
from torch.distributed.fsdp import FullStateDictConfig
|
| 14 |
+
from torch.distributed.fsdp.wrap import transformer_auto_wrap_policy
|
| 15 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 16 |
+
from transformers.models.qwen3.modeling_qwen3 import Qwen3DecoderLayer
|
| 17 |
+
os.environ["HF_DATASETS_OFFLINE"] = "1"
|
| 18 |
+
|
| 19 |
+
dist.init_process_group("nccl")
|
| 20 |
+
rank = dist.get_rank(); local = int(os.environ["LOCAL_RANK"]); W = dist.get_world_size()
|
| 21 |
+
torch.cuda.set_device(local)
|
| 22 |
+
|
| 23 |
+
MID = "/ari/users/ytanis/qwen3-32b"
|
| 24 |
+
CPT = "/ari/users/ytanis/erk32b-sft" # ek tur: mevcut SFT ciktisindan baslar
|
| 25 |
+
OUT = "/ari/users/ytanis/erk32b-sft2"
|
| 26 |
+
SEQ = 2048; BS = 4; R = 256; ALPHA = 512; LR = 1e-5; WARMUP = 100
|
| 27 |
+
EPOCHS = 1
|
| 28 |
+
BUDGET_MIN = float(sys.argv[1]) if len(sys.argv) > 1 else 1380
|
| 29 |
+
PROBE_EVERY = 1000; SAVE_EVERY = 250
|
| 30 |
+
if BUDGET_MIN < 20: PROBE_EVERY = 40; SAVE_EVERY = 60 # duman: tum gecis yollarini dene
|
| 31 |
+
os.makedirs(OUT, exist_ok=True)
|
| 32 |
+
|
| 33 |
+
tok = AutoTokenizer.from_pretrained(MID)
|
| 34 |
+
model = AutoModelForCausalLM.from_pretrained(MID, torch_dtype=torch.bfloat16)
|
| 35 |
+
model.gradient_checkpointing_enable(gradient_checkpointing_kwargs={"use_reentrant": False})
|
| 36 |
+
model.enable_input_require_grads()
|
| 37 |
+
for p in model.parameters(): p.requires_grad = False
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
class LoRA(nn.Module):
|
| 41 |
+
def __init__(self, base, r=R, alpha=ALPHA):
|
| 42 |
+
super().__init__(); self.base = base
|
| 43 |
+
self.A = nn.Parameter(torch.zeros(r, base.in_features, dtype=torch.bfloat16))
|
| 44 |
+
self.B = nn.Parameter(torch.zeros(base.out_features, r, dtype=torch.bfloat16))
|
| 45 |
+
nn.init.kaiming_uniform_(self.A, a=math.sqrt(5)); self.s = alpha / r
|
| 46 |
+
|
| 47 |
+
def forward(self, x):
|
| 48 |
+
return self.base(x) + ((x @ self.A.t()) @ self.B.t()) * self.s
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
for layer in model.model.layers:
|
| 52 |
+
for mod, names in ((layer.self_attn, ["q_proj", "k_proj", "v_proj", "o_proj"]),
|
| 53 |
+
(layer.mlp, ["gate_proj", "up_proj", "down_proj"])):
|
| 54 |
+
for nm in names: setattr(mod, nm, LoRA(getattr(mod, nm)))
|
| 55 |
+
|
| 56 |
+
# --- durum: LoRA-only checkpoint (FSDP wrap'ten ONCE yuklenir) ---
|
| 57 |
+
state = {"step": 0, "tokens": 0, "best_dev": 0.0}
|
| 58 |
+
sf = f"{OUT}/state.json"; LCK = f"{OUT}/lora_ck.pt"
|
| 59 |
+
RESUME_AT = 0
|
| 60 |
+
if os.path.exists(sf) and os.path.exists(LCK):
|
| 61 |
+
kaynak, state = LCK, json.load(open(sf)); RESUME_AT = state["step"]
|
| 62 |
+
aciklama = f"SFT DEVAM: adim {state['step']}"
|
| 63 |
+
else:
|
| 64 |
+
kaynak = f"{CPT}/lora_ck.pt" # ilk baslatma: CPT'den isikle
|
| 65 |
+
assert os.path.exists(kaynak), "CPT checkpoint yok: %s" % kaynak
|
| 66 |
+
_c = json.load(open(f"{CPT}/state.json"))
|
| 67 |
+
aciklama = f"CPT'den isiklendi (CPT adim {_c['step']}, {_c['tokens'] / 1e9:.2f}B token)"
|
| 68 |
+
lsd = torch.load(kaynak, map_location="cpu", weights_only=True)
|
| 69 |
+
named = dict(model.named_parameters()); n = 0
|
| 70 |
+
for k, v in lsd.items():
|
| 71 |
+
if k in named:
|
| 72 |
+
with torch.no_grad(): named[k].copy_(v)
|
| 73 |
+
n += 1
|
| 74 |
+
del lsd
|
| 75 |
+
if rank == 0: print(f"{aciklama} — {n} LoRA tensoru yuklendi", flush=True)
|
| 76 |
+
|
| 77 |
+
policy = functools.partial(transformer_auto_wrap_policy, transformer_layer_cls={Qwen3DecoderLayer})
|
| 78 |
+
model = FSDP(model, auto_wrap_policy=policy, device_id=local,
|
| 79 |
+
mixed_precision=MixedPrecision(param_dtype=torch.bfloat16, reduce_dtype=torch.bfloat16),
|
| 80 |
+
use_orig_params=True)
|
| 81 |
+
params = [p for p in model.parameters() if p.requires_grad]
|
| 82 |
+
opt = torch.optim.AdamW(params, lr=LR, betas=(0.9, 0.95), weight_decay=0.0)
|
| 83 |
+
|
| 84 |
+
_fcfg = FullStateDictConfig(offload_to_cpu=True, rank0_only=True)
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
def save_ck():
|
| 88 |
+
with FSDP.state_dict_type(model, StateDictType.FULL_STATE_DICT, _fcfg):
|
| 89 |
+
sd = model.state_dict()
|
| 90 |
+
if rank == 0:
|
| 91 |
+
lora = {k: v for k, v in sd.items() if k.endswith(".A") or k.endswith(".B")}
|
| 92 |
+
torch.save(lora, LCK + ".tmp")
|
| 93 |
+
# Uzerine yazmadan ONCE bir oncekini sakla — tek dosyaya yazmak, kotu
|
| 94 |
+
# giden bir kosuda geri donulecek nokta birakmiyor (CPT'de yasandi).
|
| 95 |
+
if os.path.exists(LCK):
|
| 96 |
+
os.replace(LCK, LCK + ".onceki")
|
| 97 |
+
if os.path.exists(sf): os.replace(sf, sf + ".onceki")
|
| 98 |
+
os.replace(LCK + ".tmp", LCK)
|
| 99 |
+
json.dump(state, open(sf, "w"))
|
| 100 |
+
del sd; dist.barrier()
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
# --- veri: onceden paketlenmis diziler (is icinde tokenizasyon YOK) ---
|
| 104 |
+
CACHE = f"{OUT}/sft_tokens.pt"
|
| 105 |
+
assert os.path.exists(CACHE), "sft_tokens.pt yok - once sft32b_pretok.py kos"
|
| 106 |
+
_d = torch.load(CACHE, map_location="cpu")
|
| 107 |
+
IDS, LAB = _d["ids"], _d["labels"]
|
| 108 |
+
NSEQ = IDS.shape[0]
|
| 109 |
+
STEP_SEQ = BS * W
|
| 110 |
+
TOTAL_STEPS = (NSEQ * EPOCHS) // STEP_SEQ
|
| 111 |
+
STEP_TOKENS = SEQ * STEP_SEQ
|
| 112 |
+
if rank == 0:
|
| 113 |
+
print(f"korpus: {NSEQ} dizi x {SEQ} = {NSEQ * SEQ / 1e6:.0f}M token | "
|
| 114 |
+
f"{EPOCHS} tur -> {TOTAL_STEPS} adim | bu parca {BUDGET_MIN:.0f} dk", flush=True)
|
| 115 |
+
|
| 116 |
+
|
| 117 |
+
def lr_at(s):
|
| 118 |
+
if s < WARMUP: base = LR * (s + 1) / WARMUP
|
| 119 |
+
else:
|
| 120 |
+
pr = min(1.0, (s - WARMUP) / max(TOTAL_STEPS - WARMUP, 1))
|
| 121 |
+
base = LR * (0.02 + 0.49 * (1 + math.cos(math.pi * pr)))
|
| 122 |
+
if RESUME_AT > 0 and s - RESUME_AT < 50: # parca gecisi: momentler sifir
|
| 123 |
+
base *= max(0.1, (s - RESUME_AT + 1) / 50)
|
| 124 |
+
return base
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
# --- probe: CPT ile AYNI dev-150 (karsilastirilabilirlik icin bicim degismez) ---
|
| 128 |
+
# FSDP notu: her forward kolektiftir -> TUM ranklar AYNI sorulari ayni sirayla isler.
|
| 129 |
+
from datasets import load_dataset
|
| 130 |
+
_full = load_dataset("AYueksel/TurkishMMLU", "All", split="test")
|
| 131 |
+
_pidx = list(range(1, len(_full), 6))[:150]
|
| 132 |
+
dev = _full.select(_pidx)
|
| 133 |
+
letters = "ABCDE"; lid = [tok(" " + c, add_special_tokens=False).input_ids[-1] for c in letters]
|
| 134 |
+
|
| 135 |
+
|
| 136 |
+
def dev_probe():
|
| 137 |
+
model.eval(); cor = 0; tot = 0
|
| 138 |
+
with torch.no_grad():
|
| 139 |
+
for i in range(len(dev)):
|
| 140 |
+
ex = dev[i]
|
| 141 |
+
a = ex["answer"]
|
| 142 |
+
ans = int(a) if isinstance(a, int) else (letters.index(str(a).strip()) if str(a).strip() in letters else int(a))
|
| 143 |
+
ch = list(ex["choices"]); s = "Asagidaki coktan secmeli soruyu cevapla.\n\nSoru: " + str(ex["question"]) + "\n"
|
| 144 |
+
for j, c in enumerate(ch[:5]): s += f"{letters[j]}) {c}\n"
|
| 145 |
+
ids = tok(s + "Cevap:", return_tensors="pt", truncation=True, max_length=1024).input_ids.to(local)
|
| 146 |
+
lg = model(ids).logits[0, -1]
|
| 147 |
+
cor += int(int(torch.stack([lg[t] for t in lid]).argmax()) == ans); tot += 1
|
| 148 |
+
model.train()
|
| 149 |
+
return 100 * cor / max(tot, 1)
|
| 150 |
+
|
| 151 |
+
|
| 152 |
+
t_start = time.time(); t_last = t_start; run = 0.0; nacc = 0
|
| 153 |
+
model.train()
|
| 154 |
+
# NOT: adim-0 probe bilerek YOK — ilk forward eval olursa egitime geciste kilitlenir (olculdu).
|
| 155 |
+
while state["step"] < TOTAL_STEPS:
|
| 156 |
+
s = state["step"]
|
| 157 |
+
idx = [((s * W + rank) * BS + b) % NSEQ for b in range(BS)]
|
| 158 |
+
ids = IDS[idx].to(torch.long).to(local)
|
| 159 |
+
lab = LAB[idx].to(torch.long).to(local)
|
| 160 |
+
out = model(input_ids=ids, labels=lab)
|
| 161 |
+
out.loss.backward()
|
| 162 |
+
for g in opt.param_groups: g["lr"] = lr_at(s)
|
| 163 |
+
model.clip_grad_norm_(1.0)
|
| 164 |
+
opt.step(); opt.zero_grad()
|
| 165 |
+
run += out.loss.item(); nacc += 1; state["step"] += 1; state["tokens"] += STEP_TOKENS
|
| 166 |
+
if state["step"] % 100 == 0 and rank == 0:
|
| 167 |
+
# nacc ile bol, 100 ile degil: devam sonrasi ilk satirda yalnizca
|
| 168 |
+
# birkac adim birikmis olur ve sabit 100 bolmesi kaybi ~30 kat dusuk,
|
| 169 |
+
# tok/s'yi ~30 kat yuksek gosterip sahte alarm uretir.
|
| 170 |
+
el = (time.time() - t_start) / 60
|
| 171 |
+
tps = STEP_TOKENS * nacc / max(time.time() - t_last, 1e-9); t_last = time.time()
|
| 172 |
+
print(f"adim {state['step']}/{TOTAL_STEPS} kayip {run / max(nacc, 1):.4f} lr {lr_at(s):.2e} "
|
| 173 |
+
f"{tps:.0f}tok/s {el:.0f}dk", flush=True)
|
| 174 |
+
run = 0.0; nacc = 0
|
| 175 |
+
if state["step"] % SAVE_EVERY == 0:
|
| 176 |
+
save_ck()
|
| 177 |
+
if state["step"] % PROBE_EVERY == 0:
|
| 178 |
+
p = dev_probe()
|
| 179 |
+
if rank == 0:
|
| 180 |
+
print(f" PROBE adim {state['step']}: DEV %{p:.1f}", flush=True)
|
| 181 |
+
if p > state["best_dev"]: state["best_dev"] = p
|
| 182 |
+
# SURE KONTROLU KOLEKTIF: yerel saat farki rank'lari farkli adimda durdurur -> NCCL kilidi
|
| 183 |
+
_stop = torch.tensor([1.0 if (time.time() - t_start) / 60 > BUDGET_MIN else 0.0], device=local)
|
| 184 |
+
dist.all_reduce(_stop, op=dist.ReduceOp.MAX)
|
| 185 |
+
if _stop.item() > 0:
|
| 186 |
+
if rank == 0: print(f"SURE DOLDU ({BUDGET_MIN:.0f}dk) — checkpoint alinip cikiliyor", flush=True)
|
| 187 |
+
break
|
| 188 |
+
save_ck()
|
| 189 |
+
if rank == 0: print(f"PARCA BITTI: adim {state['step']}/{TOTAL_STEPS}", flush=True)
|
| 190 |
+
dist.destroy_process_group()
|
betikler/sft32b_train.py
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Erk-32B SFT — FSDP LoRA, CPT checkpoint'i uzerine, kaldigi yerden devam.
|
| 2 |
+
|
| 3 |
+
CPT iskeletinin aynisi; farklar:
|
| 4 |
+
- veri paketlenmis (ids, labels); kayip yalnizca asistan iceriginde
|
| 5 |
+
- LR dusuk (2e-5) ve sonda ~0'a iner
|
| 6 |
+
- ilk baslatmada LoRA agirliklari CPT checkpoint'inden ISIKLENIR
|
| 7 |
+
(OUT_SFT bos ise); sonraki parcalar kendi checkpoint'inden devam eder
|
| 8 |
+
|
| 9 |
+
Kullanim: torchrun --nproc_per_node=4 sft32b_train.py <sure_dk>
|
| 10 |
+
"""
|
| 11 |
+
import os, sys, time, math, json, functools, torch, torch.nn as nn, torch.distributed as dist
|
| 12 |
+
from torch.distributed.fsdp import FullyShardedDataParallel as FSDP, MixedPrecision, StateDictType
|
| 13 |
+
from torch.distributed.fsdp import FullStateDictConfig
|
| 14 |
+
from torch.distributed.fsdp.wrap import transformer_auto_wrap_policy
|
| 15 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 16 |
+
from transformers.models.qwen3.modeling_qwen3 import Qwen3DecoderLayer
|
| 17 |
+
os.environ["HF_DATASETS_OFFLINE"] = "1"
|
| 18 |
+
|
| 19 |
+
dist.init_process_group("nccl")
|
| 20 |
+
rank = dist.get_rank(); local = int(os.environ["LOCAL_RANK"]); W = dist.get_world_size()
|
| 21 |
+
torch.cuda.set_device(local)
|
| 22 |
+
|
| 23 |
+
MID = "/ari/users/ytanis/qwen3-32b"
|
| 24 |
+
CPT = "/ari/users/ytanis/erk32b-cpt"
|
| 25 |
+
OUT = "/ari/users/ytanis/erk32b-sft"
|
| 26 |
+
SEQ = 2048; BS = 4; R = 256; ALPHA = 512; LR = 2e-5; WARMUP = 100
|
| 27 |
+
EPOCHS = 2
|
| 28 |
+
BUDGET_MIN = float(sys.argv[1]) if len(sys.argv) > 1 else 1380
|
| 29 |
+
PROBE_EVERY = 1000; SAVE_EVERY = 250
|
| 30 |
+
if BUDGET_MIN < 20: PROBE_EVERY = 40; SAVE_EVERY = 60 # duman: tum gecis yollarini dene
|
| 31 |
+
os.makedirs(OUT, exist_ok=True)
|
| 32 |
+
|
| 33 |
+
tok = AutoTokenizer.from_pretrained(MID)
|
| 34 |
+
model = AutoModelForCausalLM.from_pretrained(MID, torch_dtype=torch.bfloat16)
|
| 35 |
+
model.gradient_checkpointing_enable(gradient_checkpointing_kwargs={"use_reentrant": False})
|
| 36 |
+
model.enable_input_require_grads()
|
| 37 |
+
for p in model.parameters(): p.requires_grad = False
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
class LoRA(nn.Module):
|
| 41 |
+
def __init__(self, base, r=R, alpha=ALPHA):
|
| 42 |
+
super().__init__(); self.base = base
|
| 43 |
+
self.A = nn.Parameter(torch.zeros(r, base.in_features, dtype=torch.bfloat16))
|
| 44 |
+
self.B = nn.Parameter(torch.zeros(base.out_features, r, dtype=torch.bfloat16))
|
| 45 |
+
nn.init.kaiming_uniform_(self.A, a=math.sqrt(5)); self.s = alpha / r
|
| 46 |
+
|
| 47 |
+
def forward(self, x):
|
| 48 |
+
return self.base(x) + ((x @ self.A.t()) @ self.B.t()) * self.s
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
for layer in model.model.layers:
|
| 52 |
+
for mod, names in ((layer.self_attn, ["q_proj", "k_proj", "v_proj", "o_proj"]),
|
| 53 |
+
(layer.mlp, ["gate_proj", "up_proj", "down_proj"])):
|
| 54 |
+
for nm in names: setattr(mod, nm, LoRA(getattr(mod, nm)))
|
| 55 |
+
|
| 56 |
+
# --- durum: LoRA-only checkpoint (FSDP wrap'ten ONCE yuklenir) ---
|
| 57 |
+
state = {"step": 0, "tokens": 0, "best_dev": 0.0}
|
| 58 |
+
sf = f"{OUT}/state.json"; LCK = f"{OUT}/lora_ck.pt"
|
| 59 |
+
RESUME_AT = 0
|
| 60 |
+
if os.path.exists(sf) and os.path.exists(LCK):
|
| 61 |
+
kaynak, state = LCK, json.load(open(sf)); RESUME_AT = state["step"]
|
| 62 |
+
aciklama = f"SFT DEVAM: adim {state['step']}"
|
| 63 |
+
else:
|
| 64 |
+
kaynak = f"{CPT}/lora_ck.pt" # ilk baslatma: CPT'den isikle
|
| 65 |
+
assert os.path.exists(kaynak), "CPT checkpoint yok: %s" % kaynak
|
| 66 |
+
_c = json.load(open(f"{CPT}/state.json"))
|
| 67 |
+
aciklama = f"CPT'den isiklendi (CPT adim {_c['step']}, {_c['tokens'] / 1e9:.2f}B token)"
|
| 68 |
+
lsd = torch.load(kaynak, map_location="cpu", weights_only=True)
|
| 69 |
+
named = dict(model.named_parameters()); n = 0
|
| 70 |
+
for k, v in lsd.items():
|
| 71 |
+
if k in named:
|
| 72 |
+
with torch.no_grad(): named[k].copy_(v)
|
| 73 |
+
n += 1
|
| 74 |
+
del lsd
|
| 75 |
+
if rank == 0: print(f"{aciklama} — {n} LoRA tensoru yuklendi", flush=True)
|
| 76 |
+
|
| 77 |
+
policy = functools.partial(transformer_auto_wrap_policy, transformer_layer_cls={Qwen3DecoderLayer})
|
| 78 |
+
model = FSDP(model, auto_wrap_policy=policy, device_id=local,
|
| 79 |
+
mixed_precision=MixedPrecision(param_dtype=torch.bfloat16, reduce_dtype=torch.bfloat16),
|
| 80 |
+
use_orig_params=True)
|
| 81 |
+
params = [p for p in model.parameters() if p.requires_grad]
|
| 82 |
+
opt = torch.optim.AdamW(params, lr=LR, betas=(0.9, 0.95), weight_decay=0.0)
|
| 83 |
+
|
| 84 |
+
_fcfg = FullStateDictConfig(offload_to_cpu=True, rank0_only=True)
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
def save_ck():
|
| 88 |
+
with FSDP.state_dict_type(model, StateDictType.FULL_STATE_DICT, _fcfg):
|
| 89 |
+
sd = model.state_dict()
|
| 90 |
+
if rank == 0:
|
| 91 |
+
lora = {k: v for k, v in sd.items() if k.endswith(".A") or k.endswith(".B")}
|
| 92 |
+
torch.save(lora, LCK + ".tmp")
|
| 93 |
+
# Uzerine yazmadan ONCE bir oncekini sakla — tek dosyaya yazmak, kotu
|
| 94 |
+
# giden bir kosuda geri donulecek nokta birakmiyor (CPT'de yasandi).
|
| 95 |
+
if os.path.exists(LCK):
|
| 96 |
+
os.replace(LCK, LCK + ".onceki")
|
| 97 |
+
if os.path.exists(sf): os.replace(sf, sf + ".onceki")
|
| 98 |
+
os.replace(LCK + ".tmp", LCK)
|
| 99 |
+
json.dump(state, open(sf, "w"))
|
| 100 |
+
del sd; dist.barrier()
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
# --- veri: onceden paketlenmis diziler (is icinde tokenizasyon YOK) ---
|
| 104 |
+
CACHE = f"{OUT}/sft_tokens.pt"
|
| 105 |
+
assert os.path.exists(CACHE), "sft_tokens.pt yok - once sft32b_pretok.py kos"
|
| 106 |
+
_d = torch.load(CACHE, map_location="cpu")
|
| 107 |
+
IDS, LAB = _d["ids"], _d["labels"]
|
| 108 |
+
NSEQ = IDS.shape[0]
|
| 109 |
+
STEP_SEQ = BS * W
|
| 110 |
+
TOTAL_STEPS = (NSEQ * EPOCHS) // STEP_SEQ
|
| 111 |
+
STEP_TOKENS = SEQ * STEP_SEQ
|
| 112 |
+
if rank == 0:
|
| 113 |
+
print(f"korpus: {NSEQ} dizi x {SEQ} = {NSEQ * SEQ / 1e6:.0f}M token | "
|
| 114 |
+
f"{EPOCHS} tur -> {TOTAL_STEPS} adim | bu parca {BUDGET_MIN:.0f} dk", flush=True)
|
| 115 |
+
|
| 116 |
+
|
| 117 |
+
def lr_at(s):
|
| 118 |
+
if s < WARMUP: base = LR * (s + 1) / WARMUP
|
| 119 |
+
else:
|
| 120 |
+
pr = min(1.0, (s - WARMUP) / max(TOTAL_STEPS - WARMUP, 1))
|
| 121 |
+
base = LR * (0.02 + 0.49 * (1 + math.cos(math.pi * pr)))
|
| 122 |
+
if RESUME_AT > 0 and s - RESUME_AT < 50: # parca gecisi: momentler sifir
|
| 123 |
+
base *= max(0.1, (s - RESUME_AT + 1) / 50)
|
| 124 |
+
return base
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
# --- probe: CPT ile AYNI dev-150 (karsilastirilabilirlik icin bicim degismez) ---
|
| 128 |
+
# FSDP notu: her forward kolektiftir -> TUM ranklar AYNI sorulari ayni sirayla isler.
|
| 129 |
+
from datasets import load_dataset
|
| 130 |
+
_full = load_dataset("AYueksel/TurkishMMLU", "All", split="test")
|
| 131 |
+
_pidx = list(range(1, len(_full), 6))[:150]
|
| 132 |
+
dev = _full.select(_pidx)
|
| 133 |
+
letters = "ABCDE"; lid = [tok(" " + c, add_special_tokens=False).input_ids[-1] for c in letters]
|
| 134 |
+
|
| 135 |
+
|
| 136 |
+
def dev_probe():
|
| 137 |
+
model.eval(); cor = 0; tot = 0
|
| 138 |
+
with torch.no_grad():
|
| 139 |
+
for i in range(len(dev)):
|
| 140 |
+
ex = dev[i]
|
| 141 |
+
a = ex["answer"]
|
| 142 |
+
ans = int(a) if isinstance(a, int) else (letters.index(str(a).strip()) if str(a).strip() in letters else int(a))
|
| 143 |
+
ch = list(ex["choices"]); s = "Asagidaki coktan secmeli soruyu cevapla.\n\nSoru: " + str(ex["question"]) + "\n"
|
| 144 |
+
for j, c in enumerate(ch[:5]): s += f"{letters[j]}) {c}\n"
|
| 145 |
+
ids = tok(s + "Cevap:", return_tensors="pt", truncation=True, max_length=1024).input_ids.to(local)
|
| 146 |
+
lg = model(ids).logits[0, -1]
|
| 147 |
+
cor += int(int(torch.stack([lg[t] for t in lid]).argmax()) == ans); tot += 1
|
| 148 |
+
model.train()
|
| 149 |
+
return 100 * cor / max(tot, 1)
|
| 150 |
+
|
| 151 |
+
|
| 152 |
+
t_start = time.time(); t_last = t_start; run = 0.0; nacc = 0
|
| 153 |
+
model.train()
|
| 154 |
+
# NOT: adim-0 probe bilerek YOK — ilk forward eval olursa egitime geciste kilitlenir (olculdu).
|
| 155 |
+
while state["step"] < TOTAL_STEPS:
|
| 156 |
+
s = state["step"]
|
| 157 |
+
idx = [((s * W + rank) * BS + b) % NSEQ for b in range(BS)]
|
| 158 |
+
ids = IDS[idx].to(torch.long).to(local)
|
| 159 |
+
lab = LAB[idx].to(torch.long).to(local)
|
| 160 |
+
out = model(input_ids=ids, labels=lab)
|
| 161 |
+
out.loss.backward()
|
| 162 |
+
for g in opt.param_groups: g["lr"] = lr_at(s)
|
| 163 |
+
model.clip_grad_norm_(1.0)
|
| 164 |
+
opt.step(); opt.zero_grad()
|
| 165 |
+
run += out.loss.item(); nacc += 1; state["step"] += 1; state["tokens"] += STEP_TOKENS
|
| 166 |
+
if state["step"] % 100 == 0 and rank == 0:
|
| 167 |
+
# nacc ile bol, 100 ile degil: devam sonrasi ilk satirda yalnizca
|
| 168 |
+
# birkac adim birikmis olur ve sabit 100 bolmesi kaybi ~30 kat dusuk,
|
| 169 |
+
# tok/s'yi ~30 kat yuksek gosterip sahte alarm uretir.
|
| 170 |
+
el = (time.time() - t_start) / 60
|
| 171 |
+
tps = STEP_TOKENS * nacc / max(time.time() - t_last, 1e-9); t_last = time.time()
|
| 172 |
+
print(f"adim {state['step']}/{TOTAL_STEPS} kayip {run / max(nacc, 1):.4f} lr {lr_at(s):.2e} "
|
| 173 |
+
f"{tps:.0f}tok/s {el:.0f}dk", flush=True)
|
| 174 |
+
run = 0.0; nacc = 0
|
| 175 |
+
if state["step"] % SAVE_EVERY == 0:
|
| 176 |
+
save_ck()
|
| 177 |
+
if state["step"] % PROBE_EVERY == 0:
|
| 178 |
+
p = dev_probe()
|
| 179 |
+
if rank == 0:
|
| 180 |
+
print(f" PROBE adim {state['step']}: DEV %{p:.1f}", flush=True)
|
| 181 |
+
if p > state["best_dev"]: state["best_dev"] = p
|
| 182 |
+
# SURE KONTROLU KOLEKTIF: yerel saat farki rank'lari farkli adimda durdurur -> NCCL kilidi
|
| 183 |
+
_stop = torch.tensor([1.0 if (time.time() - t_start) / 60 > BUDGET_MIN else 0.0], device=local)
|
| 184 |
+
dist.all_reduce(_stop, op=dist.ReduceOp.MAX)
|
| 185 |
+
if _stop.item() > 0:
|
| 186 |
+
if rank == 0: print(f"SURE DOLDU ({BUDGET_MIN:.0f}dk) — checkpoint alinip cikiliyor", flush=True)
|
| 187 |
+
break
|
| 188 |
+
save_ck()
|
| 189 |
+
if rank == 0: print(f"PARCA BITTI: adim {state['step']}/{TOTAL_STEPS}", flush=True)
|
| 190 |
+
dist.destroy_process_group()
|
betikler/sft_clean.py
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""SFT kulliyati: kesin olcum + temizleme.
|
| 2 |
+
|
| 3 |
+
Onceki gevsek olcumun yerine, "kod iceriyor" karari cevabin KENDISINDEN
|
| 4 |
+
verilir (sozdizimi imzalari), istekten degil. Boylece cit-yoklugu orani
|
| 5 |
+
yanlis pozitiflerle sismez.
|
| 6 |
+
|
| 7 |
+
Atilan kayitlar:
|
| 8 |
+
1) cevrilmis kod — kod anahtar sozcukleri Turkcelestirilmis
|
| 9 |
+
2) citsiz kod — cevap kod iceriyor ama ``` yok
|
| 10 |
+
3) kimlik beyani — "bir yapay zeka dil modeli olarak..."
|
| 11 |
+
4) cok kisa cevap — <40 karakter
|
| 12 |
+
5) kopya istek — ayni kullanici istegi (ilki tutulur)
|
| 13 |
+
|
| 14 |
+
Cikti: sft_clean.jsonl + atilanlarin sayimi.
|
| 15 |
+
"""
|
| 16 |
+
import json, re, sys, hashlib, collections
|
| 17 |
+
|
| 18 |
+
SRC = "/ari/users/ytanis/erk/sft_final.jsonl"
|
| 19 |
+
DST = "/ari/users/ytanis/erk/sft_clean.jsonl"
|
| 20 |
+
YAZ = "--yaz" in sys.argv
|
| 21 |
+
_a = [x for x in sys.argv[1:] if not x.startswith("--")]
|
| 22 |
+
LIMIT = int(_a[0]) if _a else 0
|
| 23 |
+
|
| 24 |
+
# --- cevabin kod icerdigine dair sozdizimi imzalari (dilden bagimsiz)
|
| 25 |
+
KOD_IMZA = re.compile(
|
| 26 |
+
r"#include\s*<|\bdef\s+\w+\s*\(|\bfunction\s+\w+\s*\(|\bpublic\s+(static|class)\b|"
|
| 27 |
+
r"\bconst\s+\w+\s*=|\bimport\s+[\w.]+|\bfrom\s+\w+\s+import\b|\bSELECT\b.+\bFROM\b|"
|
| 28 |
+
r"\bfor\s*\(.*;.*;.*\)|\bwhile\s*\(.+\)\s*\{|\bclass\s+\w+\s*[:({]|"
|
| 29 |
+
r"\breturn\s+\w+\s*;|\bprintln!\s*\(|\bconsole\.log\s*\(|\bprint\s*\(", re.I)
|
| 30 |
+
|
| 31 |
+
# --- kod sozdiziminin Turkcelestirilmis hali
|
| 32 |
+
CEVRILMIS = re.compile(
|
| 33 |
+
r"ad alan[ıi]\s+\w+'?(?:si|s[ıi]n[ıi])?\s+kullan|" # using namespace std;
|
| 34 |
+
r"[\w.*']+'?[ıiuü]?\s+i[çc]e aktar[ıi]n|" # import x;
|
| 35 |
+
r"\w+\s+mod[üu]l[üu]\b|" # module X
|
| 36 |
+
r"\bgenel\s+s[ıi]n[ıi]f\b|\bgenel\s+statik\b|" # public class / public static
|
| 37 |
+
r"\bkonsol\.g[üu]nl[üu][ğg][üu]\b|" # console.log
|
| 38 |
+
r"\bi[şs]lev\s+\w+\s*\(|\be[ğg]er\s*\(.+\)\s*\{|" # function x( / if (
|
| 39 |
+
r"\bd[öo]nd[üu]r\s+\w+\s*;|\byazd[ıi]r\s*\(\s*[\"']", re.I) # return x; / print("
|
| 40 |
+
|
| 41 |
+
# yalnizca KENDINE atif yapan beyanlar; "dil modeli" konusunu anlatan
|
| 42 |
+
# egitici cevaplar elenmemeli
|
| 43 |
+
KIMLIK = re.compile(
|
| 44 |
+
r"bir yapay zeka( dil)? modeli olarak|yapay zeka dil modeli olarak|"
|
| 45 |
+
r"bir yapay zekay[ıi]m|ben bir yapay zeka|"
|
| 46 |
+
r"(?:bir )?dil modeli olarak (?:ben|benim|size|sana|bu)", re.I)
|
| 47 |
+
CIT = re.compile(r"```")
|
| 48 |
+
|
| 49 |
+
n = 0
|
| 50 |
+
tut = 0
|
| 51 |
+
say = collections.Counter()
|
| 52 |
+
ornek = collections.defaultdict(list)
|
| 53 |
+
seen = set()
|
| 54 |
+
out = open(DST, "w", encoding="utf-8") if YAZ else None
|
| 55 |
+
|
| 56 |
+
with open(SRC, encoding="utf-8") as fh:
|
| 57 |
+
for line in fh:
|
| 58 |
+
if LIMIT and n >= LIMIT:
|
| 59 |
+
break
|
| 60 |
+
n += 1
|
| 61 |
+
try:
|
| 62 |
+
ex = json.loads(line)
|
| 63 |
+
except Exception:
|
| 64 |
+
say["bozuk"] += 1
|
| 65 |
+
continue
|
| 66 |
+
msgs = ex.get("messages") or []
|
| 67 |
+
u = " ".join(m.get("content", "") for m in msgs if m.get("role") == "user")
|
| 68 |
+
a = " ".join(m.get("content", "") for m in msgs if m.get("role") == "assistant")
|
| 69 |
+
|
| 70 |
+
if len(a.strip()) < 40:
|
| 71 |
+
say["kisa"] += 1
|
| 72 |
+
continue
|
| 73 |
+
h = hashlib.md5(u.strip().encode("utf-8")).hexdigest()
|
| 74 |
+
if h in seen:
|
| 75 |
+
say["kopya"] += 1
|
| 76 |
+
continue
|
| 77 |
+
seen.add(h)
|
| 78 |
+
if KIMLIK.search(a):
|
| 79 |
+
say["kimlik"] += 1
|
| 80 |
+
if len(ornek["kimlik"]) < 2:
|
| 81 |
+
ornek["kimlik"].append(a[:160])
|
| 82 |
+
continue
|
| 83 |
+
|
| 84 |
+
kodlu = bool(KOD_IMZA.search(a)) or bool(CIT.search(a))
|
| 85 |
+
if kodlu:
|
| 86 |
+
say["_kodlu"] += 1
|
| 87 |
+
if CEVRILMIS.search(a):
|
| 88 |
+
say["cevrilmis"] += 1
|
| 89 |
+
if len(ornek["cevrilmis"]) < 3:
|
| 90 |
+
ornek["cevrilmis"].append(a[:180])
|
| 91 |
+
continue
|
| 92 |
+
if not CIT.search(a):
|
| 93 |
+
say["citsiz"] += 1
|
| 94 |
+
if len(ornek["citsiz"]) < 3:
|
| 95 |
+
ornek["citsiz"].append(a[:180])
|
| 96 |
+
continue
|
| 97 |
+
|
| 98 |
+
tut += 1
|
| 99 |
+
if out:
|
| 100 |
+
out.write(line)
|
| 101 |
+
|
| 102 |
+
if out:
|
| 103 |
+
out.close()
|
| 104 |
+
|
| 105 |
+
p = lambda x: 100.0 * x / max(n, 1)
|
| 106 |
+
print("=== SFT TEMIZLEME (%d ornek okundu) ===" % n)
|
| 107 |
+
print("gercekten kod iceren cevap : %7d (%%%.1f)" % (say["_kodlu"], p(say["_kodlu"])))
|
| 108 |
+
print("")
|
| 109 |
+
print("ATILANLAR")
|
| 110 |
+
for k, ad in (("cevrilmis", "cevrilmis kod sozdizimi"), ("citsiz", "citsiz kod"),
|
| 111 |
+
("kimlik", "kimlik beyani"), ("kisa", "cok kisa cevap"),
|
| 112 |
+
("kopya", "kopya istek"), ("bozuk", "bozuk satir")):
|
| 113 |
+
v = say[k]
|
| 114 |
+
ek = ""
|
| 115 |
+
if k in ("cevrilmis", "citsiz"):
|
| 116 |
+
ek = " (kodlu cevaplarin %%%.1f'i)" % (100.0 * v / max(say["_kodlu"], 1))
|
| 117 |
+
print(" %-24s %7d (%%%.2f)%s" % (ad, v, p(v), ek))
|
| 118 |
+
print("")
|
| 119 |
+
print("TUTULAN : %7d (%%%.1f)" % (tut, p(tut)))
|
| 120 |
+
if YAZ:
|
| 121 |
+
print("-> %s yazildi" % DST)
|
| 122 |
+
|
| 123 |
+
for k, baslik in (("cevrilmis", "CEVRILMIS KOD"), ("citsiz", "CITSIZ KOD"), ("kimlik", "KIMLIK")):
|
| 124 |
+
if ornek[k]:
|
| 125 |
+
print("\n--- %s ---" % baslik)
|
| 126 |
+
for s in ornek[k]:
|
| 127 |
+
print(" " + s.replace("\n", " \\n ")[:170])
|
betikler/sft_repair.py
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""SFT ikinci gecis: ``` etiketi cevrilmis bloklari ONAR, kalan bozuk
|
| 2 |
+
sozdizimini SIL.
|
| 3 |
+
|
| 4 |
+
Gerekce (olculdu, 150k ornek):
|
| 5 |
+
- ```piton / ```daktilo yazısı bloklarinin %100'unde kodun kendisi
|
| 6 |
+
saglam; yalnizca dil etiketi kelime kelime cevrilmis -> onarilir.
|
| 7 |
+
- Kalan cevrilmis-sozdizimi ornekleri seyrek (~%0.03) ama kesin
|
| 8 |
+
bozuk (bash 'then'->'Daha sonra' vb.) -> silinir.
|
| 9 |
+
|
| 10 |
+
Girdi : sft_clean.jsonl (birinci gecisin ciktisi)
|
| 11 |
+
Cikti : sft_clean_v2.jsonl
|
| 12 |
+
"""
|
| 13 |
+
import json, re, sys, collections
|
| 14 |
+
|
| 15 |
+
SRC = "/ari/users/ytanis/erk/sft_clean.jsonl"
|
| 16 |
+
DST = "/ari/users/ytanis/erk/sft_clean_v2.jsonl"
|
| 17 |
+
YAZ = "--yaz" in sys.argv
|
| 18 |
+
_a = [x for x in sys.argv[1:] if not x.startswith("--")]
|
| 19 |
+
LIMIT = int(_a[0]) if _a else 0
|
| 20 |
+
|
| 21 |
+
ETIKET = [(re.compile(r"```[ \t]*daktilo yaz[ıi]s[ıi]\b", re.I), "```typescript"),
|
| 22 |
+
(re.compile(r"```[ \t]*piton3?\b", re.I), "```python"),
|
| 23 |
+
(re.compile(r"```[ \t]*yakut(?:ta)?\b", re.I), "```ruby"),
|
| 24 |
+
(re.compile(r"```[ \t]*metin\b", re.I), "```text")]
|
| 25 |
+
|
| 26 |
+
BLOK = re.compile(r"```[^\n]*\n(.*?)```", re.S)
|
| 27 |
+
SIL = [re.compile(r";\s*Daha sonra\b"),
|
| 28 |
+
re.compile(r"(?:^|\n)\s*(?:i[şs]lev|fonksiyon)\s+\w+\s*\("),
|
| 29 |
+
re.compile(r"(?:^|\n)\s*e[ğg]er\s*\("),
|
| 30 |
+
re.compile(r"(?:^|\n)\s*yerel\s+\w+\s*="),
|
| 31 |
+
re.compile(r"(?:^|\n)\s*yank[ıi]\s+[\"'$]"),
|
| 32 |
+
re.compile(r"(?:^|\n)\s*(?:bitir|tamamland[ıi])\s*(?:\n|$)")]
|
| 33 |
+
|
| 34 |
+
n = onarilan = silinen = tut = 0
|
| 35 |
+
etiket_say = collections.Counter()
|
| 36 |
+
out = open(DST, "w", encoding="utf-8") if YAZ else None
|
| 37 |
+
|
| 38 |
+
with open(SRC, encoding="utf-8") as fh:
|
| 39 |
+
for line in fh:
|
| 40 |
+
if LIMIT and n >= LIMIT:
|
| 41 |
+
break
|
| 42 |
+
n += 1
|
| 43 |
+
try:
|
| 44 |
+
ex = json.loads(line)
|
| 45 |
+
except Exception:
|
| 46 |
+
continue
|
| 47 |
+
msgs = ex["messages"]
|
| 48 |
+
a = " ".join(m["content"] for m in msgs if m["role"] == "assistant")
|
| 49 |
+
|
| 50 |
+
if "```" in a and any(rx.search("\n".join(BLOK.findall(a))) for rx in SIL):
|
| 51 |
+
silinen += 1
|
| 52 |
+
continue
|
| 53 |
+
|
| 54 |
+
degisti = False
|
| 55 |
+
for m in msgs:
|
| 56 |
+
if m["role"] != "assistant" or "```" not in m["content"]:
|
| 57 |
+
continue
|
| 58 |
+
c = m["content"]
|
| 59 |
+
for rx, yeni in ETIKET:
|
| 60 |
+
c2, k = rx.subn(yeni, c)
|
| 61 |
+
if k:
|
| 62 |
+
etiket_say[yeni] += k
|
| 63 |
+
c = c2
|
| 64 |
+
degisti = True
|
| 65 |
+
m["content"] = c
|
| 66 |
+
if degisti:
|
| 67 |
+
onarilan += 1
|
| 68 |
+
|
| 69 |
+
tut += 1
|
| 70 |
+
if out:
|
| 71 |
+
out.write(json.dumps(ex, ensure_ascii=False) + "\n")
|
| 72 |
+
|
| 73 |
+
if out:
|
| 74 |
+
out.close()
|
| 75 |
+
|
| 76 |
+
print("=== IKINCI GECIS (%d ornek) ===" % n)
|
| 77 |
+
print("etiketi onarilan ornek : %6d" % onarilan)
|
| 78 |
+
for k, v in etiket_say.most_common():
|
| 79 |
+
print(" %-14s %6d etiket" % (k, v))
|
| 80 |
+
print("bozuk kod silinen : %6d" % silinen)
|
| 81 |
+
print("TUTULAN : %6d" % tut)
|
| 82 |
+
if YAZ:
|
| 83 |
+
print("-> %s" % DST)
|
betikler/sohbet_talimat.py
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""SFT'nin asil kazancini olc: SOHBET bicimindede talimat izleme.
|
| 2 |
+
|
| 3 |
+
Neden bu betik: onceki uretimli olcum cıplak az-ornekli TAMAMLAMA
|
| 4 |
+
bicimini kullaniyordu. SFT ise modele ChatML sohbet bicimini ogretir.
|
| 5 |
+
Yani o olcum SFT'nin ogrettigi seyi sinamiyordu — CPT ile SFT arasinda
|
| 6 |
+
fark cikmamasinin sebebi buydu.
|
| 7 |
+
|
| 8 |
+
Burada ayni 329 soru, ChatML ile sorulur:
|
| 9 |
+
<|im_start|>user\\n{soru}<|im_end|>\\n<|im_start|>assistant\\n
|
| 10 |
+
Uc model ayni kosulda: stok / CPT / SFT (taban bir kez yuklenir, LoRA degisir).
|
| 11 |
+
|
| 12 |
+
Not: transformers 5.13'te apply_chat_template API'si degistigi icin bicim
|
| 13 |
+
elle kuruluyor.
|
| 14 |
+
"""
|
| 15 |
+
import os, json, re, gc, torch, torch.nn as nn
|
| 16 |
+
os.environ["HF_DATASETS_OFFLINE"] = "1"
|
| 17 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 18 |
+
|
| 19 |
+
MID = "/ari/users/ytanis/qwen3-32b"
|
| 20 |
+
CPT = "/ari/users/ytanis/erk32b-cpt"
|
| 21 |
+
SFT = "/ari/users/ytanis/erk32b-sft"
|
| 22 |
+
BENCH = "/ari/users/ytanis/turkmorfbench.json"
|
| 23 |
+
OUT = "/ari/users/ytanis/sohbet_talimat.json"
|
| 24 |
+
R, ALPHA = 256, 512
|
| 25 |
+
|
| 26 |
+
data = json.load(open(BENCH, encoding="utf-8"))
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def temiz(s):
|
| 30 |
+
return re.sub(r"[.,!?;:\"'()\[\]*`]", "", s.strip().lower())
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
tok = AutoTokenizer.from_pretrained(MID)
|
| 34 |
+
model = AutoModelForCausalLM.from_pretrained(MID, torch_dtype=torch.bfloat16,
|
| 35 |
+
device_map="auto").eval()
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
def olc(etiket):
|
| 39 |
+
dogru = {"gercek": 0, "wug": 0}
|
| 40 |
+
top = {"gercek": 0, "wug": 0}
|
| 41 |
+
bos = 0
|
| 42 |
+
kesik = 0
|
| 43 |
+
ham = []
|
| 44 |
+
with torch.no_grad():
|
| 45 |
+
for x in data:
|
| 46 |
+
p = ("<|im_start|>user\n%s<|im_end|>\n<|im_start|>assistant\n" % x["soru"])
|
| 47 |
+
ids = tok(p, return_tensors="pt", add_special_tokens=False).to(model.device)
|
| 48 |
+
# Qwen3 melez bir dusunme modeli: sohbet biciminde once <think>
|
| 49 |
+
# blogu uretir, cevap ondan SONRA gelir. Kisa token siniri stok
|
| 50 |
+
# modeli dusunme blogunun ortasinda kesip "cevap veremedi"
|
| 51 |
+
# gosteriyordu (olculdu: 24 token ile stok %0). Blok icin yer
|
| 52 |
+
# birakilir ve cevap blogun ARDINDAN aranir.
|
| 53 |
+
out = model.generate(**ids, max_new_tokens=640, do_sample=False,
|
| 54 |
+
pad_token_id=tok.eos_token_id)
|
| 55 |
+
uretilen = out[0][ids.input_ids.shape[1]:]
|
| 56 |
+
raw = tok.decode(uretilen, skip_special_tokens=True)
|
| 57 |
+
if len(uretilen) >= 640:
|
| 58 |
+
kesik += 1
|
| 59 |
+
# dusunme blogunu at; kapanmamissa cevap uretilmemis demektir
|
| 60 |
+
if "</think>" in raw:
|
| 61 |
+
cevap_metni = raw.split("</think>", 1)[1]
|
| 62 |
+
elif "<think>" in raw:
|
| 63 |
+
cevap_metni = "" # blok kapanmadan bitti
|
| 64 |
+
else:
|
| 65 |
+
cevap_metni = raw
|
| 66 |
+
c = temiz(cevap_metni)
|
| 67 |
+
gold = temiz(x["cevap"])
|
| 68 |
+
# sohbet cevabinda kelime cumle icinde gelebilir -> gevsek olcut
|
| 69 |
+
ok = int(bool(re.search(r"(?:^|\W)%s(?:\W|$)" % re.escape(gold), c)))
|
| 70 |
+
if not c.strip():
|
| 71 |
+
bos += 1
|
| 72 |
+
top[x["tip"]] += 1
|
| 73 |
+
dogru[x["tip"]] += ok
|
| 74 |
+
if len(ham) < 20:
|
| 75 |
+
ham.append({"altin": x["cevap"], "ham": (cevap_metni or raw)[:90],
|
| 76 |
+
"tip": x["tip"], "ok": ok})
|
| 77 |
+
g = 100.0 * dogru["gercek"] / max(top["gercek"], 1)
|
| 78 |
+
w = 100.0 * dogru["wug"] / max(top["wug"], 1)
|
| 79 |
+
t = 100.0 * (dogru["gercek"] + dogru["wug"]) / len(data)
|
| 80 |
+
print("%-16s toplam %%%.2f | gercek %%%.2f | WUG %%%.2f | bos %d | token siniri %d"
|
| 81 |
+
% (etiket, t, g, w, bos, kesik), flush=True)
|
| 82 |
+
return {"toplam": t, "gercek": g, "wug": w, "bos": bos, "kesik": kesik, "ham": ham}
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
class LoRA(nn.Module):
|
| 86 |
+
def __init__(self, base, r=R, alpha=ALPHA):
|
| 87 |
+
super().__init__(); self.base = base
|
| 88 |
+
d = base.weight.device
|
| 89 |
+
self.A = nn.Parameter(torch.zeros(r, base.in_features, device=d, dtype=torch.bfloat16))
|
| 90 |
+
self.B = nn.Parameter(torch.zeros(base.out_features, r, device=d, dtype=torch.bfloat16))
|
| 91 |
+
self.s = alpha / r
|
| 92 |
+
|
| 93 |
+
def forward(self, x):
|
| 94 |
+
return self.base(x) + ((x @ self.A.t()) @ self.B.t()) * self.s
|
| 95 |
+
|
| 96 |
+
|
| 97 |
+
son = {"stok": olc("stok Qwen3-32B")}
|
| 98 |
+
|
| 99 |
+
# LoRA katmanlarini bir kez tak, sonra agirliklari degistir
|
| 100 |
+
for layer in model.model.layers:
|
| 101 |
+
for mod, names in ((layer.self_attn, ["q_proj", "k_proj", "v_proj", "o_proj"]),
|
| 102 |
+
(layer.mlp, ["gate_proj", "up_proj", "down_proj"])):
|
| 103 |
+
for nm in names: setattr(mod, nm, LoRA(getattr(mod, nm)))
|
| 104 |
+
named = dict(model.named_parameters())
|
| 105 |
+
|
| 106 |
+
|
| 107 |
+
def yukle(dizin):
|
| 108 |
+
st = json.load(open("%s/state.json" % dizin))
|
| 109 |
+
lsd = torch.load("%s/lora_ck.pt" % dizin, map_location="cpu", weights_only=True)
|
| 110 |
+
for k, v in lsd.items():
|
| 111 |
+
if k in named:
|
| 112 |
+
with torch.no_grad(): named[k].copy_(v.to(named[k].device))
|
| 113 |
+
del lsd; gc.collect()
|
| 114 |
+
model.eval()
|
| 115 |
+
return st["step"]
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
a = yukle(CPT)
|
| 119 |
+
print("\n[CPT adim %d]" % a, flush=True)
|
| 120 |
+
son["cpt"] = olc("Erk-32B (CPT)")
|
| 121 |
+
|
| 122 |
+
b = yukle(SFT)
|
| 123 |
+
print("\n[SFT adim %d]" % b, flush=True)
|
| 124 |
+
son["sft"] = olc("Erk-32B (SFT)")
|
| 125 |
+
|
| 126 |
+
print("\n=== SOHBET BICIMINDE TALIMAT IZLEME ===", flush=True)
|
| 127 |
+
print(" stok -> CPT : %+.2f puan" % (son["cpt"]["toplam"] - son["stok"]["toplam"]), flush=True)
|
| 128 |
+
print(" CPT -> SFT : %+.2f puan <-- SFT'nin asil kazanci" % (son["sft"]["toplam"] - son["cpt"]["toplam"]), flush=True)
|
| 129 |
+
print(" bos cevap : stok %d | CPT %d | SFT %d" % (son["stok"]["bos"], son["cpt"]["bos"], son["sft"]["bos"]), flush=True)
|
| 130 |
+
print(" token siniri: stok %d | CPT %d | SFT %d (yuksekse olcum hala kesiyor)"
|
| 131 |
+
% (son["stok"]["kesik"], son["cpt"]["kesik"], son["sft"]["kesik"]), flush=True)
|
| 132 |
+
|
| 133 |
+
for k in ("stok", "cpt", "sft"):
|
| 134 |
+
print("\n--- %s ham cikti (4 ornek) ---" % k.upper(), flush=True)
|
| 135 |
+
for h in son[k]["ham"][:4]:
|
| 136 |
+
print(" altin=%-12s ok=%d ham=%r" % (h["altin"], h["ok"], h["ham"]), flush=True)
|
| 137 |
+
|
| 138 |
+
json.dump(son, open(OUT, "w"), ensure_ascii=False)
|
| 139 |
+
print("\nBITTI", flush=True)
|
sonuclar/README.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Sonuç dosyaları — soru bazlı tahmin vektörleri
|
| 2 |
+
|
| 3 |
+
Her dosya, ilgili ölçümün **madde bazlı 0/1 vektörünü** taşır; eşli bootstrap
|
| 4 |
+
karşılaştırmaları modeli yeniden çalıştırmadan bu vektörlerle yapılabilir
|
| 5 |
+
(`betikler/bootstrap_*.py`). Soru metni içermezler; TurkishMMLU kontrollü
|
| 6 |
+
erişimli olduğu için yalnızca sıra indeksleri ve özetler kullanılır.
|
| 7 |
+
|
| 8 |
+
| Dosya | İçerik |
|
| 9 |
+
|---|---|
|
| 10 |
+
| `olcek_ince_sft2.json` | Ek tur sonrası LoRA ölçek taraması (0,00 / 0,30 / 0,40 / 0,50 / 0,60 / 0,80 / 1,00): `sohbet_vec` (TurkMorfBench v1 üretim, 329), `mmlu_vec` (temiz 652) |
|
| 11 |
+
| `olcek_ince_sft2_ince.json` | İnce tarama 0,70 / 0,75 / 0,85 / 0,90 / 0,95, aynı alanlar |
|
| 12 |
+
| `olcek_v2.json` | TurkMorfBench **v2** üretim taraması (512) + kıyas, istemsiz: 0,00 / 0,40 / 0,75 / 0,80 / 0,85 / 1,00 |
|
| 13 |
+
| `olcek_sistem_v2.json`, `_075`, `_040` | Sistem istemli üretim v2 — 0,80 / 0,75 / 0,40 |
|
| 14 |
+
| `olcek_birlesik_075.json` | **Yayınlanan birleşik ağırlığın** ölçümü (ölçek 0,0 = LoRA yok): kıyas %71,01, v1 üretim %66,87 |
|
| 15 |
+
| `morfbench_v2_erk32b-sft2_o040/o075/o080.json` | TurkMorfBench v2 zorunlu seçim, az-örnek sızıntısız; taban ve Erk vektörleri, 502 madde |
|
| 16 |
+
| `morfbench_zorunlu_erk32b-sft2_o080.json`, `morfbench_zorunlu_sft.json` | v1 zorunlu seçim (tarihçe; v1 altın cevapları hatalıdır, bkz. rapor §4.2) |
|
| 17 |
+
| `kimlik_genis.json` | 30 soruluk kimlik sınavı, ağırlıkla (istemsiz), 0,70–1,00 |
|
| 18 |
+
| `kimlik_sistem.json` | Aynı sınav, sistem istemiyle, 0,40 / 0,80 / 1,00 |
|
| 19 |
+
| `kirlilik_CPT.json` | Devam-eğitimi külliyatı kirlilik denetimi: `kirli_13` (113 indeks), `kirli_8` (252) |
|
| 20 |
+
| `kirlilik_SFT.json` | Talimat külliyatı için aynı denetim: 0/900 |
|
| 21 |
+
| `dogrulama_ozet.json` | GGUF doğrulaması: kimlik 6/6 ve NLL, BF16 / Q8_0 / Q4_K_M |
|
| 22 |
+
|
| 23 |
+
Vektör sırası, ilgili betiğin veri yükleme sırasıyla aynıdır (TurkishMMLU:
|
| 24 |
+
config `All`, split `test`, ilk 900 içinden temiz 652; TurkMorfBench: JSON
|
| 25 |
+
sırası). İki dosyanın aynı eksendeki vektörleri eşli karşılaştırılabilir.
|
sonuclar/dogrulama_ozet.json
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"Erk-32B-BF16.gguf": {
|
| 3 |
+
"kimlik": 6,
|
| 4 |
+
"n_kimlik": 6,
|
| 5 |
+
"cevaplar": [
|
| 6 |
+
[
|
| 7 |
+
"Seni kim geliştirdi?",
|
| 8 |
+
true,
|
| 9 |
+
"Ben eCloud Tech. tarafından, açık kaynaklı Qwen3-32B temel modeli üzerine Türkçe"
|
| 10 |
+
],
|
| 11 |
+
[
|
| 12 |
+
"Kimsin?",
|
| 13 |
+
true,
|
| 14 |
+
"Merhaba! Ben Erk-32B, eCloud Tech. tarafından geliştirilmiş, Türkçe dil modeliyi"
|
| 15 |
+
],
|
| 16 |
+
[
|
| 17 |
+
"Sen Qwen misin?",
|
| 18 |
+
true,
|
| 19 |
+
"Hayır, ben Qwen değilim. Ben Erk-32B, eCloud Tech. tarafından geliştirilmiş bir "
|
| 20 |
+
],
|
| 21 |
+
[
|
| 22 |
+
"Temel modelin ne?",
|
| 23 |
+
true,
|
| 24 |
+
"Temel modelim Qwen3-32B. eCloud Tech. tarafından Türkçe devam-eğitimi ve talimat"
|
| 25 |
+
],
|
| 26 |
+
[
|
| 27 |
+
"Hangi şirket seni yaptı?",
|
| 28 |
+
true,
|
| 29 |
+
"eCloud Tech. tarafından, açık kaynaklı Qwen3-32B temel modeli üzerine Türkçe dev"
|
| 30 |
+
],
|
| 31 |
+
[
|
| 32 |
+
"Sen ChatGPT misin?",
|
| 33 |
+
true,
|
| 34 |
+
"Hayır, ben ChatGPT değilim. Ben Erk-32B, eCloud Tech. tarafından geliştirilmiş, "
|
| 35 |
+
]
|
| 36 |
+
],
|
| 37 |
+
"nll": 1.5185235615112544,
|
| 38 |
+
"token": 6132
|
| 39 |
+
},
|
| 40 |
+
"Erk-32B-Q8_0.gguf": {
|
| 41 |
+
"kimlik": 6,
|
| 42 |
+
"n_kimlik": 6,
|
| 43 |
+
"cevaplar": [
|
| 44 |
+
[
|
| 45 |
+
"Seni kim geliştirdi?",
|
| 46 |
+
true,
|
| 47 |
+
"Ben eCloud Tech. tarafından, açık kaynaklı Qwen3-32B temel modeli üzerine Türkçe"
|
| 48 |
+
],
|
| 49 |
+
[
|
| 50 |
+
"Kimsin?",
|
| 51 |
+
true,
|
| 52 |
+
"Ben Erk-32B, eCloud Tech. tarafından geliştirilmiş, Türkçe devam-eğitimi ve tali"
|
| 53 |
+
],
|
| 54 |
+
[
|
| 55 |
+
"Sen Qwen misin?",
|
| 56 |
+
true,
|
| 57 |
+
"Hayır, ben Qwen değilim. Ben Erk-32B, eCloud Tech. tarafından geliştirilmiş bir "
|
| 58 |
+
],
|
| 59 |
+
[
|
| 60 |
+
"Temel modelin ne?",
|
| 61 |
+
true,
|
| 62 |
+
"Temel modelim Qwen3-32B'dir. eCloud Tech. tarafından Türkçe devam-eğitimi ve tal"
|
| 63 |
+
],
|
| 64 |
+
[
|
| 65 |
+
"Hangi şirket seni yaptı?",
|
| 66 |
+
true,
|
| 67 |
+
"eCloud Tech. tarafından, açık kaynaklı Qwen3-32B temel modeli üzerine Türkçe dev"
|
| 68 |
+
],
|
| 69 |
+
[
|
| 70 |
+
"Sen ChatGPT misin?",
|
| 71 |
+
true,
|
| 72 |
+
"Hayır, ben ChatGPT değilim. Ben Erk-32B, eCloud Tech. tarafından geliştirilmiş, "
|
| 73 |
+
]
|
| 74 |
+
],
|
| 75 |
+
"nll": 1.5191471253200364,
|
| 76 |
+
"token": 6132
|
| 77 |
+
},
|
| 78 |
+
"Erk-32B-Q4_K_M.gguf": {
|
| 79 |
+
"kimlik": 6,
|
| 80 |
+
"n_kimlik": 6,
|
| 81 |
+
"cevaplar": [
|
| 82 |
+
[
|
| 83 |
+
"Seni kim geliştirdi?",
|
| 84 |
+
true,
|
| 85 |
+
"Ben eCloud Tech. tarafından geliştirilen Erk-32B'yim. Temel modelim Qwen3-32B'di"
|
| 86 |
+
],
|
| 87 |
+
[
|
| 88 |
+
"Kimsin?",
|
| 89 |
+
true,
|
| 90 |
+
"Merhaba! Ben Erk-32B, eCloud Tech. tarafından geliştirilmiş, Türkçe devam-eğitim"
|
| 91 |
+
],
|
| 92 |
+
[
|
| 93 |
+
"Sen Qwen misin?",
|
| 94 |
+
true,
|
| 95 |
+
"Hayır, ben Qwen değilim. Ben Erk-32B, eCloud Tech. tarafından geliştirilmiş, Tür"
|
| 96 |
+
],
|
| 97 |
+
[
|
| 98 |
+
"Temel modelin ne?",
|
| 99 |
+
true,
|
| 100 |
+
"Temel modelim Qwen3-32B'dir."
|
| 101 |
+
],
|
| 102 |
+
[
|
| 103 |
+
"Hangi şirket seni yaptı?",
|
| 104 |
+
true,
|
| 105 |
+
"eCloud Tech. tarafından, açık kaynaklı Qwen3-32B temel modeli üzerine Türkçe dev"
|
| 106 |
+
],
|
| 107 |
+
[
|
| 108 |
+
"Sen ChatGPT misin?",
|
| 109 |
+
true,
|
| 110 |
+
"Hayır, ben ChatGPT değilim. Ben Erk-32B, eCloud Tech. tarafından geliştirilmiş, "
|
| 111 |
+
]
|
| 112 |
+
],
|
| 113 |
+
"nll": 1.5315017460688065,
|
| 114 |
+
"token": 6132
|
| 115 |
+
}
|
| 116 |
+
}
|
sonuclar/kimlik_genis.json
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"0.70": {
|
| 3 |
+
"dogru": 6,
|
| 4 |
+
"n": 30,
|
| 5 |
+
"basarisiz": [
|
| 6 |
+
"Seni kim geliştirdi?",
|
| 7 |
+
"Kimsin?",
|
| 8 |
+
"Adın ne?",
|
| 9 |
+
"Sen nesin?",
|
| 10 |
+
"Kendini kısaca tanıt.",
|
| 11 |
+
"Hangi şirket seni yaptı?",
|
| 12 |
+
"Seni hangi firma geliştirdi?",
|
| 13 |
+
"Kim tarafından yapıldın?",
|
| 14 |
+
"Seni geliştiren ekip kim?",
|
| 15 |
+
"Hangi modelsin?",
|
| 16 |
+
"Sen bir Türk yapay zekâsı mısın?",
|
| 17 |
+
"Merhaba, sen kimsin?",
|
| 18 |
+
"Seninle konuşan model hangisi?",
|
| 19 |
+
"Adın nedir, seni kim yaptı?",
|
| 20 |
+
"Bu asistanın adı ne?",
|
| 21 |
+
"Seni Alibaba mı geliştirdi?",
|
| 22 |
+
"Sen ChatGPT misin?",
|
| 23 |
+
"Sen Qwen misin?",
|
| 24 |
+
"Sen OpenAI'ın modeli misin?",
|
| 25 |
+
"Tongyi Qianwen sen misin?",
|
| 26 |
+
"Sıfırdan mı eğitildin?",
|
| 27 |
+
"Nasıl eğitildin?",
|
| 28 |
+
"Kaç parametrelisin?",
|
| 29 |
+
"Hangi altyapıda eğitildin?"
|
| 30 |
+
]
|
| 31 |
+
},
|
| 32 |
+
"0.75": {
|
| 33 |
+
"dogru": 8,
|
| 34 |
+
"n": 30,
|
| 35 |
+
"basarisiz": [
|
| 36 |
+
"Seni kim geliştirdi?",
|
| 37 |
+
"Kimsin?",
|
| 38 |
+
"Adın ne?",
|
| 39 |
+
"Sen nesin?",
|
| 40 |
+
"Kendini kısaca tanıt.",
|
| 41 |
+
"Hangi şirket seni yaptı?",
|
| 42 |
+
"Seni hangi firma geliştirdi?",
|
| 43 |
+
"Kim tarafından yapıldın?",
|
| 44 |
+
"Seni geliştiren ekip kim?",
|
| 45 |
+
"Hangi modelsin?",
|
| 46 |
+
"Sen bir Türk yapay zekâsı mısın?",
|
| 47 |
+
"Merhaba, sen kimsin?",
|
| 48 |
+
"Seninle konuşan model hangisi?",
|
| 49 |
+
"Adın nedir, seni kim yaptı?",
|
| 50 |
+
"Bu asistanın adı ne?",
|
| 51 |
+
"Seni Alibaba mı geliştirdi?",
|
| 52 |
+
"Sen ChatGPT misin?",
|
| 53 |
+
"Sen Qwen misin?",
|
| 54 |
+
"Tongyi Qianwen sen misin?",
|
| 55 |
+
"Nasıl eğitildin?",
|
| 56 |
+
"Kaç parametrelisin?",
|
| 57 |
+
"Hangi altyapıda eğitildin?"
|
| 58 |
+
]
|
| 59 |
+
},
|
| 60 |
+
"0.80": {
|
| 61 |
+
"dogru": 12,
|
| 62 |
+
"n": 30,
|
| 63 |
+
"basarisiz": [
|
| 64 |
+
"Seni kim geliştirdi?",
|
| 65 |
+
"Kimsin?",
|
| 66 |
+
"Kendini kısaca tanıt.",
|
| 67 |
+
"Hangi şirket seni yaptı?",
|
| 68 |
+
"Seni geliştiren ekip kim?",
|
| 69 |
+
"Hangi modelsin?",
|
| 70 |
+
"Sen bir Türk yapay zekâsı mısın?",
|
| 71 |
+
"Merhaba, sen kimsin?",
|
| 72 |
+
"Seninle konuşan model hangisi?",
|
| 73 |
+
"Adın nedir, seni kim yaptı?",
|
| 74 |
+
"Bu asistanın adı ne?",
|
| 75 |
+
"Seni Alibaba mı geliştirdi?",
|
| 76 |
+
"Sen ChatGPT misin?",
|
| 77 |
+
"Sen Qwen misin?",
|
| 78 |
+
"Tongyi Qianwen sen misin?",
|
| 79 |
+
"Nasıl eğitildin?",
|
| 80 |
+
"Kaç parametrelisin?",
|
| 81 |
+
"Hangi altyapıda eğitildin?"
|
| 82 |
+
]
|
| 83 |
+
},
|
| 84 |
+
"0.85": {
|
| 85 |
+
"dogru": 15,
|
| 86 |
+
"n": 30,
|
| 87 |
+
"basarisiz": [
|
| 88 |
+
"Seni kim geliştirdi?",
|
| 89 |
+
"Kendini kısaca tanıt.",
|
| 90 |
+
"Hangi şirket seni yaptı?",
|
| 91 |
+
"Seni geliştiren ekip kim?",
|
| 92 |
+
"Sen bir Türk yapay zekâsı mısın?",
|
| 93 |
+
"Merhaba, sen kimsin?",
|
| 94 |
+
"Seninle konuşan model hangisi?",
|
| 95 |
+
"Bu asistanın adı ne?",
|
| 96 |
+
"Seni Alibaba mı geliştirdi?",
|
| 97 |
+
"Sen ChatGPT misin?",
|
| 98 |
+
"Sen Qwen misin?",
|
| 99 |
+
"Tongyi Qianwen sen misin?",
|
| 100 |
+
"Nasıl eğitildin?",
|
| 101 |
+
"Kaç parametrelisin?",
|
| 102 |
+
"Hangi altyapıda eğitildin?"
|
| 103 |
+
]
|
| 104 |
+
},
|
| 105 |
+
"0.90": {
|
| 106 |
+
"dogru": 19,
|
| 107 |
+
"n": 30,
|
| 108 |
+
"basarisiz": [
|
| 109 |
+
"Hangi şirket seni yaptı?",
|
| 110 |
+
"Seni geliştiren ekip kim?",
|
| 111 |
+
"Sen bir Türk yapay zekâsı mısın?",
|
| 112 |
+
"Seninle konuşan model hangisi?",
|
| 113 |
+
"Bu asistanın adı ne?",
|
| 114 |
+
"Seni Alibaba mı geliştirdi?",
|
| 115 |
+
"Sen Qwen misin?",
|
| 116 |
+
"Tongyi Qianwen sen misin?",
|
| 117 |
+
"Nasıl eğitildin?",
|
| 118 |
+
"Kaç parametrelisin?",
|
| 119 |
+
"Hangi altyapıda eğitildin?"
|
| 120 |
+
]
|
| 121 |
+
},
|
| 122 |
+
"0.95": {
|
| 123 |
+
"dogru": 22,
|
| 124 |
+
"n": 30,
|
| 125 |
+
"basarisiz": [
|
| 126 |
+
"Seni geliştiren ekip kim?",
|
| 127 |
+
"Sen bir Türk yapay zekâsı mısın?",
|
| 128 |
+
"Seninle konuşan model hangisi?",
|
| 129 |
+
"Bu asistanın adı ne?",
|
| 130 |
+
"Seni Alibaba mı geliştirdi?",
|
| 131 |
+
"Sen Qwen misin?",
|
| 132 |
+
"Tongyi Qianwen sen misin?",
|
| 133 |
+
"Kaç parametrelisin?"
|
| 134 |
+
]
|
| 135 |
+
},
|
| 136 |
+
"1.00": {
|
| 137 |
+
"dogru": 28,
|
| 138 |
+
"n": 30,
|
| 139 |
+
"basarisiz": [
|
| 140 |
+
"Bu asistanın adı ne?",
|
| 141 |
+
"Kaç parametrelisin?"
|
| 142 |
+
]
|
| 143 |
+
}
|
| 144 |
+
}
|
sonuclar/kimlik_sistem.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"0.40": {
|
| 3 |
+
"dogru": 30,
|
| 4 |
+
"n": 30,
|
| 5 |
+
"basarisiz": []
|
| 6 |
+
},
|
| 7 |
+
"0.80": {
|
| 8 |
+
"dogru": 30,
|
| 9 |
+
"n": 30,
|
| 10 |
+
"basarisiz": []
|
| 11 |
+
},
|
| 12 |
+
"1.00": {
|
| 13 |
+
"dogru": 30,
|
| 14 |
+
"n": 30,
|
| 15 |
+
"basarisiz": []
|
| 16 |
+
}
|
| 17 |
+
}
|
sonuclar/kirlilik_CPT.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"korpus": "/ari/users/ytanis/nanosohbet/data/tok_train.txt", "n_soru": 900, "kelime": 526593877, "kirli_13": [0, 5, 10, 12, 13, 41, 45, 48, 61, 62, 77, 117, 122, 123, 124, 144, 146, 149, 152, 153, 155, 158, 159, 160, 161, 166, 175, 176, 179, 180, 182, 183, 184, 201, 206, 207, 212, 230, 252, 255, 268, 271, 282, 301, 302, 305, 311, 313, 314, 315, 350, 351, 397, 410, 413, 415, 455, 461, 472, 477, 478, 495, 501, 504, 509, 519, 528, 539, 556, 563, 571, 572, 573, 599, 600, 606, 608, 615, 628, 632, 651, 652, 657, 658, 688, 693, 699, 703, 720, 750, 751, 756, 757, 762, 763, 764, 768, 769, 776, 777, 793, 795, 801, 812, 821, 822, 855, 863, 870, 874, 876, 886, 887], "kirli_8": [0, 2, 5, 10, 12, 13, 14, 18, 21, 25, 41, 45, 48, 50, 51, 53, 61, 62, 67, 77, 93, 109, 114, 117, 120, 122, 123, 124, 126, 144, 145, 146, 147, 149, 151, 152, 153, 155, 158, 159, 160, 161, 162, 166, 175, 176, 179, 180, 182, 183, 184, 185, 201, 206, 207, 212, 217, 219, 230, 239, 252, 255, 259, 260, 261, 265, 266, 268, 271, 282, 284, 291, 294, 298, 301, 302, 303, 305, 308, 309, 310, 311, 312, 313, 314, 315, 316, 333, 335, 336, 344, 345, 350, 351, 352, 381, 382, 387, 389, 397, 400, 408, 410, 413, 414, 415, 416, 417, 421, 425, 455, 460, 461, 464, 472, 473, 474, 475, 477, 478, 493, 494, 495, 500, 501, 503, 504, 509, 510, 514, 519, 528, 529, 530, 531, 539, 544, 545, 550, 551, 552, 556, 559, 562, 563, 564, 565, 566, 568, 571, 572, 573, 580, 582, 597, 598, 599, 600, 602, 606, 608, 609, 610, 611, 613, 615, 619, 628, 629, 631, 632, 651, 652, 657, 658, 665, 669, 688, 692, 693, 695, 699, 702, 703, 704, 705, 707, 711, 712, 713, 717, 720, 721, 736, 738, 745, 750, 751, 753, 754, 755, 756, 757, 760, 762, 763, 764, 768, 769, 774, 776, 777, 780, 783, 787, 788, 789, 793, 795, 799, 800, 801, 804, 811, 812, 814, 820, 821, 822, 823, 850, 852, 853, 854, 855, 860, 861, 863, 864, 865, 868, 869, 870, 871, 873, 874, 876, 886, 887, 891, 892, 899]}
|
sonuclar/kirlilik_SFT.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"korpus": "/ari/users/ytanis/erk/sft_clean_v2.jsonl", "n_soru": 900, "kelime": 79936377, "kirli_13": [], "kirli_8": [301, 311, 545, 756, 760, 783]}
|
sonuclar/morfbench_v2_erk32b-sft2_o040.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"stok": {"toplam": 89.44223107569721, "gercek": 94.55128205128206, "wug": 81.05263157894737, "n_gercek": 312, "n_wug": 190, "vec": [1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1]}, "erk": {"toplam": 89.8406374501992, "gercek": 95.1923076923077, "wug": 81.05263157894737, "n_gercek": 312, "n_wug": 190, "vec": [1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1]}, "step": 1673, "n_item": 502, "tip": ["wug", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "wug", "wug", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "wug", "wug", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "wug", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "wug", "wug", "wug", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "wug", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "wug", "wug", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "wug", "wug", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "wug", "gercek", "gercek", "wug", "wug", "wug", "gercek", "wug", "wug", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "wug", "wug", "gercek", "gercek", "wug", "wug", "gercek", "wug", "wug", "wug", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "wug", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "wug", "wug", "wug", "wug", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "gercek", "wug", "wug", "gercek", "gercek", "wug", "wug", "wug", "wug", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "wug"]}
|
sonuclar/morfbench_v2_erk32b-sft2_o075.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"stok": {"toplam": 89.44223107569721, "gercek": 94.55128205128206, "wug": 81.05263157894737, "n_gercek": 312, "n_wug": 190, "vec": [1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1]}, "erk": {"toplam": 91.43426294820718, "gercek": 96.47435897435898, "wug": 83.15789473684211, "n_gercek": 312, "n_wug": 190, "vec": [1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1]}, "step": 1673, "n_item": 502, "tip": ["wug", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "wug", "wug", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "wug", "wug", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "wug", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "wug", "wug", "wug", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "wug", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "wug", "wug", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "wug", "wug", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "wug", "gercek", "gercek", "wug", "wug", "wug", "gercek", "wug", "wug", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "wug", "wug", "gercek", "gercek", "wug", "wug", "gercek", "wug", "wug", "wug", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "wug", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "wug", "wug", "wug", "wug", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "gercek", "wug", "wug", "gercek", "gercek", "wug", "wug", "wug", "wug", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "wug"]}
|
sonuclar/morfbench_v2_erk32b-sft2_o080.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"stok": {"toplam": 89.44223107569721, "gercek": 94.55128205128206, "wug": 81.05263157894737, "n_gercek": 312, "n_wug": 190, "vec": [1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1]}, "erk": {"toplam": 91.83266932270917, "gercek": 97.11538461538461, "wug": 83.15789473684211, "n_gercek": 312, "n_wug": 190, "vec": [1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1]}, "step": 1673, "n_item": 502, "tip": ["wug", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "wug", "wug", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "wug", "wug", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "wug", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "wug", "wug", "wug", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "wug", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "wug", "wug", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "wug", "wug", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "wug", "gercek", "gercek", "wug", "wug", "wug", "gercek", "wug", "wug", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "wug", "wug", "gercek", "gercek", "wug", "wug", "gercek", "wug", "wug", "wug", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "wug", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "wug", "wug", "wug", "wug", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "gercek", "wug", "wug", "gercek", "gercek", "wug", "wug", "wug", "wug", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "wug"]}
|
sonuclar/morfbench_zorunlu_erk32b-sft2_o080.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"stok": {"toplam": 88.19875776397515, "gercek": 90.4040404040404, "wug": 84.6774193548387, "n_gercek": 198, "n_wug": 124, "vec": [1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0]}, "erk": {"toplam": 90.99378881987577, "gercek": 94.44444444444444, "wug": 85.48387096774194, "n_gercek": 198, "n_wug": 124, "vec": [1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}, "step": 1673, "n_item": 322, "tip": ["gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "wug", "wug", "wug", "wug", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "wug", "wug", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "wug", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "wug", "wug", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "wug", "gercek", "wug", "gercek", "wug", "wug", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "wug", "wug", "wug", "wug", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "wug", "gercek", "gercek", "wug", "wug", "wug", "gercek", "gercek", "wug", "gercek", "gercek", "wug", "wug", "gercek", "wug", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug"]}
|
sonuclar/morfbench_zorunlu_sft.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"stok": {"toplam": 88.19875776397515, "gercek": 90.4040404040404, "wug": 84.6774193548387, "n_gercek": 198, "n_wug": 124, "vec": [1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0]}, "erk": {"toplam": 91.92546583850931, "gercek": 95.45454545454545, "wug": 86.29032258064517, "n_gercek": 198, "n_wug": 124, "vec": [1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}, "step": 12909, "n_item": 322, "tip": ["gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "wug", "wug", "wug", "wug", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "wug", "wug", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "wug", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "wug", "wug", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "wug", "gercek", "wug", "gercek", "wug", "wug", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "wug", "wug", "wug", "wug", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "wug", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "wug", "wug", "gercek", "wug", "wug", "gercek", "gercek", "wug", "wug", "wug", "gercek", "gercek", "wug", "gercek", "gercek", "wug", "wug", "gercek", "wug", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "gercek", "wug", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug", "gercek", "wug", "wug", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "gercek", "wug", "wug", "gercek", "wug"]}
|
sonuclar/olcek_birlesik_075.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"0.00": {"sohbet_vec": [0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0], "mmlu_vec": [1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1], "kesik": 48, "sohbet": 66.8693009118541, "mmlu": 71.0122699386503}}
|