Sentence Similarity
sentence-transformers
Safetensors
Northern Hindko
Southern Hindko
xlm-roberta
feature-extraction
hindko
embeddings
low-resource
urdu-script
perso-arabic
Eval Results (legacy)
text-embeddings-inference
Instructions to use junaid008/hindko-embeddings with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- sentence-transformers
How to use junaid008/hindko-embeddings with sentence-transformers:
from sentence_transformers import SentenceTransformer model = SentenceTransformer("junaid008/hindko-embeddings") sentences = [ "The weather is lovely today.", "It's so sunny outside!", "He drove to the stadium." ] embeddings = model.encode(sentences) similarities = model.similarity(embeddings, embeddings) print(similarities.shape) # [3, 3] - Notebooks
- Google Colab
- Kaggle
Hindko Embeddings v1.0.0: multilingual-e5-large fine-tuned for Hindko (model, card, benchmarks)
Browse files- .gitattributes +8 -0
- 1_Pooling/config.json +5 -0
- 2_Normalize/config.json +4 -0
- LICENSE +446 -0
- README.md +425 -0
- benchmarks/00_scorecard.png +3 -0
- benchmarks/01_test_overall_all_models.png +3 -0
- benchmarks/02_test_per_task.png +3 -0
- benchmarks/03_dev_candidates.png +3 -0
- benchmarks/04_round1_vs_round2.png +3 -0
- benchmarks/05_size_vs_score.png +3 -0
- benchmarks/06_booktitle_detail.png +3 -0
- config.json +30 -0
- config_sentence_transformers.json +14 -0
- eval/results.csv +28 -0
- eval/selection.json +40 -0
- eval/training.json +106 -0
- make_charts.py +402 -0
- model.safetensors +3 -0
- modules.json +20 -0
- sentence_bert_config.json +10 -0
- tokenizer.json +3 -0
- tokenizer_config.json +22 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,11 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
benchmarks/00_scorecard.png filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
benchmarks/01_test_overall_all_models.png filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
benchmarks/02_test_per_task.png filter=lfs diff=lfs merge=lfs -text
|
| 39 |
+
benchmarks/03_dev_candidates.png filter=lfs diff=lfs merge=lfs -text
|
| 40 |
+
benchmarks/04_round1_vs_round2.png filter=lfs diff=lfs merge=lfs -text
|
| 41 |
+
benchmarks/05_size_vs_score.png filter=lfs diff=lfs merge=lfs -text
|
| 42 |
+
benchmarks/06_booktitle_detail.png filter=lfs diff=lfs merge=lfs -text
|
| 43 |
+
tokenizer.json filter=lfs diff=lfs merge=lfs -text
|
1_Pooling/config.json
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"embedding_dimension": 1024,
|
| 3 |
+
"pooling_mode": "mean",
|
| 4 |
+
"include_prompt": true
|
| 5 |
+
}
|
2_Normalize/config.json
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"module_input_name": "sentence_embedding",
|
| 3 |
+
"module_output_name": "sentence_embedding"
|
| 4 |
+
}
|
LICENSE
ADDED
|
@@ -0,0 +1,446 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Hindko Embeddings 1.0.0 (junaid008/hindko-embeddings)
|
| 2 |
+
Copyright (c) 2026 junaid008
|
| 3 |
+
|
| 4 |
+
The files in this repository (model weights, configuration, model card,
|
| 5 |
+
evaluation outputs and benchmark images) are licensed under the Creative
|
| 6 |
+
Commons Attribution 4.0 International License (CC BY 4.0), reproduced below
|
| 7 |
+
and at https://creativecommons.org/licenses/by/4.0/legalcode
|
| 8 |
+
|
| 9 |
+
Attribution: "Hindko Embeddings" by junaid008, https://huggingface.co/junaid008/hindko-embeddings
|
| 10 |
+
|
| 11 |
+
The model is a fine-tuned version of intfloat/multilingual-e5-large, which is
|
| 12 |
+
released under the MIT License. Its copyright and permission notice is
|
| 13 |
+
reproduced in the Third-party notice at the end of this file and applies to
|
| 14 |
+
the portions of the base model contained in the weights, tokenizer and
|
| 15 |
+
configuration files.
|
| 16 |
+
|
| 17 |
+
The licence covers the files in this repository only. The texts the model
|
| 18 |
+
was trained and evaluated on are not included and no rights in them are
|
| 19 |
+
granted.
|
| 20 |
+
|
| 21 |
+
-----------------------------------------------------------------------
|
| 22 |
+
|
| 23 |
+
Attribution 4.0 International
|
| 24 |
+
|
| 25 |
+
=======================================================================
|
| 26 |
+
|
| 27 |
+
Creative Commons Corporation ("Creative Commons") is not a law firm and
|
| 28 |
+
does not provide legal services or legal advice. Distribution of
|
| 29 |
+
Creative Commons public licenses does not create a lawyer-client or
|
| 30 |
+
other relationship. Creative Commons makes its licenses and related
|
| 31 |
+
information available on an "as-is" basis. Creative Commons gives no
|
| 32 |
+
warranties regarding its licenses, any material licensed under their
|
| 33 |
+
terms and conditions, or any related information. Creative Commons
|
| 34 |
+
disclaims all liability for damages resulting from their use to the
|
| 35 |
+
fullest extent possible.
|
| 36 |
+
|
| 37 |
+
Using Creative Commons Public Licenses
|
| 38 |
+
|
| 39 |
+
Creative Commons public licenses provide a standard set of terms and
|
| 40 |
+
conditions that creators and other rights holders may use to share
|
| 41 |
+
original works of authorship and other material subject to copyright
|
| 42 |
+
and certain other rights specified in the public license below. The
|
| 43 |
+
following considerations are for informational purposes only, are not
|
| 44 |
+
exhaustive, and do not form part of our licenses.
|
| 45 |
+
|
| 46 |
+
Considerations for licensors: Our public licenses are
|
| 47 |
+
intended for use by those authorized to give the public
|
| 48 |
+
permission to use material in ways otherwise restricted by
|
| 49 |
+
copyright and certain other rights. Our licenses are
|
| 50 |
+
irrevocable. Licensors should read and understand the terms
|
| 51 |
+
and conditions of the license they choose before applying it.
|
| 52 |
+
Licensors should also secure all rights necessary before
|
| 53 |
+
applying our licenses so that the public can reuse the
|
| 54 |
+
material as expected. Licensors should clearly mark any
|
| 55 |
+
material not subject to the license. This includes other CC-
|
| 56 |
+
licensed material, or material used under an exception or
|
| 57 |
+
limitation to copyright. More considerations for licensors:
|
| 58 |
+
wiki.creativecommons.org/Considerations_for_licensors
|
| 59 |
+
|
| 60 |
+
Considerations for the public: By using one of our public
|
| 61 |
+
licenses, a licensor grants the public permission to use the
|
| 62 |
+
licensed material under specified terms and conditions. If
|
| 63 |
+
the licensor's permission is not necessary for any reason--for
|
| 64 |
+
example, because of any applicable exception or limitation to
|
| 65 |
+
copyright--then that use is not regulated by the license. Our
|
| 66 |
+
licenses grant only permissions under copyright and certain
|
| 67 |
+
other rights that a licensor has authority to grant. Use of
|
| 68 |
+
the licensed material may still be restricted for other
|
| 69 |
+
reasons, including because others have copyright or other
|
| 70 |
+
rights in the material. A licensor may make special requests,
|
| 71 |
+
such as asking that all changes be marked or described.
|
| 72 |
+
Although not required by our licenses, you are encouraged to
|
| 73 |
+
respect those requests where reasonable. More considerations
|
| 74 |
+
for the public:
|
| 75 |
+
wiki.creativecommons.org/Considerations_for_licensees
|
| 76 |
+
|
| 77 |
+
=======================================================================
|
| 78 |
+
|
| 79 |
+
Creative Commons Attribution 4.0 International Public License
|
| 80 |
+
|
| 81 |
+
By exercising the Licensed Rights (defined below), You accept and agree
|
| 82 |
+
to be bound by the terms and conditions of this Creative Commons
|
| 83 |
+
Attribution 4.0 International Public License ("Public License"). To the
|
| 84 |
+
extent this Public License may be interpreted as a contract, You are
|
| 85 |
+
granted the Licensed Rights in consideration of Your acceptance of
|
| 86 |
+
these terms and conditions, and the Licensor grants You such rights in
|
| 87 |
+
consideration of benefits the Licensor receives from making the
|
| 88 |
+
Licensed Material available under these terms and conditions.
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
Section 1 -- Definitions.
|
| 92 |
+
|
| 93 |
+
a. Adapted Material means material subject to Copyright and Similar
|
| 94 |
+
Rights that is derived from or based upon the Licensed Material
|
| 95 |
+
and in which the Licensed Material is translated, altered,
|
| 96 |
+
arranged, transformed, or otherwise modified in a manner requiring
|
| 97 |
+
permission under the Copyright and Similar Rights held by the
|
| 98 |
+
Licensor. For purposes of this Public License, where the Licensed
|
| 99 |
+
Material is a musical work, performance, or sound recording,
|
| 100 |
+
Adapted Material is always produced where the Licensed Material is
|
| 101 |
+
synched in timed relation with a moving image.
|
| 102 |
+
|
| 103 |
+
b. Adapter's License means the license You apply to Your Copyright
|
| 104 |
+
and Similar Rights in Your contributions to Adapted Material in
|
| 105 |
+
accordance with the terms and conditions of this Public License.
|
| 106 |
+
|
| 107 |
+
c. Copyright and Similar Rights means copyright and/or similar rights
|
| 108 |
+
closely related to copyright including, without limitation,
|
| 109 |
+
performance, broadcast, sound recording, and Sui Generis Database
|
| 110 |
+
Rights, without regard to how the rights are labeled or
|
| 111 |
+
categorized. For purposes of this Public License, the rights
|
| 112 |
+
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
| 113 |
+
Rights.
|
| 114 |
+
|
| 115 |
+
d. Effective Technological Measures means those measures that, in the
|
| 116 |
+
absence of proper authority, may not be circumvented under laws
|
| 117 |
+
fulfilling obligations under Article 11 of the WIPO Copyright
|
| 118 |
+
Treaty adopted on December 20, 1996, and/or similar international
|
| 119 |
+
agreements.
|
| 120 |
+
|
| 121 |
+
e. Exceptions and Limitations means fair use, fair dealing, and/or
|
| 122 |
+
any other exception or limitation to Copyright and Similar Rights
|
| 123 |
+
that applies to Your use of the Licensed Material.
|
| 124 |
+
|
| 125 |
+
f. Licensed Material means the artistic or literary work, database,
|
| 126 |
+
or other material to which the Licensor applied this Public
|
| 127 |
+
License.
|
| 128 |
+
|
| 129 |
+
g. Licensed Rights means the rights granted to You subject to the
|
| 130 |
+
terms and conditions of this Public License, which are limited to
|
| 131 |
+
all Copyright and Similar Rights that apply to Your use of the
|
| 132 |
+
Licensed Material and that the Licensor has authority to license.
|
| 133 |
+
|
| 134 |
+
h. Licensor means the individual(s) or entity(ies) granting rights
|
| 135 |
+
under this Public License.
|
| 136 |
+
|
| 137 |
+
i. Share means to provide material to the public by any means or
|
| 138 |
+
process that requires permission under the Licensed Rights, such
|
| 139 |
+
as reproduction, public display, public performance, distribution,
|
| 140 |
+
dissemination, communication, or importation, and to make material
|
| 141 |
+
available to the public including in ways that members of the
|
| 142 |
+
public may access the material from a place and at a time
|
| 143 |
+
individually chosen by them.
|
| 144 |
+
|
| 145 |
+
j. Sui Generis Database Rights means rights other than copyright
|
| 146 |
+
resulting from Directive 96/9/EC of the European Parliament and of
|
| 147 |
+
the Council of 11 March 1996 on the legal protection of databases,
|
| 148 |
+
as amended and/or succeeded, as well as other essentially
|
| 149 |
+
equivalent rights anywhere in the world.
|
| 150 |
+
|
| 151 |
+
k. You means the individual or entity exercising the Licensed Rights
|
| 152 |
+
under this Public License. Your has a corresponding meaning.
|
| 153 |
+
|
| 154 |
+
|
| 155 |
+
Section 2 -- Scope.
|
| 156 |
+
|
| 157 |
+
a. License grant.
|
| 158 |
+
|
| 159 |
+
1. Subject to the terms and conditions of this Public License,
|
| 160 |
+
the Licensor hereby grants You a worldwide, royalty-free,
|
| 161 |
+
non-sublicensable, non-exclusive, irrevocable license to
|
| 162 |
+
exercise the Licensed Rights in the Licensed Material to:
|
| 163 |
+
|
| 164 |
+
a. reproduce and Share the Licensed Material, in whole or
|
| 165 |
+
in part; and
|
| 166 |
+
|
| 167 |
+
b. produce, reproduce, and Share Adapted Material.
|
| 168 |
+
|
| 169 |
+
2. Exceptions and Limitations. For the avoidance of doubt, where
|
| 170 |
+
Exceptions and Limitations apply to Your use, this Public
|
| 171 |
+
License does not apply, and You do not need to comply with
|
| 172 |
+
its terms and conditions.
|
| 173 |
+
|
| 174 |
+
3. Term. The term of this Public License is specified in Section
|
| 175 |
+
6(a).
|
| 176 |
+
|
| 177 |
+
4. Media and formats; technical modifications allowed. The
|
| 178 |
+
Licensor authorizes You to exercise the Licensed Rights in
|
| 179 |
+
all media and formats whether now known or hereafter created,
|
| 180 |
+
and to make technical modifications necessary to do so. The
|
| 181 |
+
Licensor waives and/or agrees not to assert any right or
|
| 182 |
+
authority to forbid You from making technical modifications
|
| 183 |
+
necessary to exercise the Licensed Rights, including
|
| 184 |
+
technical modifications necessary to circumvent Effective
|
| 185 |
+
Technological Measures. For purposes of this Public License,
|
| 186 |
+
simply making modifications authorized by this Section 2(a)
|
| 187 |
+
(4) never produces Adapted Material.
|
| 188 |
+
|
| 189 |
+
5. Downstream recipients.
|
| 190 |
+
|
| 191 |
+
a. Offer from the Licensor -- Licensed Material. Every
|
| 192 |
+
recipient of the Licensed Material automatically
|
| 193 |
+
receives an offer from the Licensor to exercise the
|
| 194 |
+
Licensed Rights under the terms and conditions of this
|
| 195 |
+
Public License.
|
| 196 |
+
|
| 197 |
+
b. No downstream restrictions. You may not offer or impose
|
| 198 |
+
any additional or different terms or conditions on, or
|
| 199 |
+
apply any Effective Technological Measures to, the
|
| 200 |
+
Licensed Material if doing so restricts exercise of the
|
| 201 |
+
Licensed Rights by any recipient of the Licensed
|
| 202 |
+
Material.
|
| 203 |
+
|
| 204 |
+
6. No endorsement. Nothing in this Public License constitutes or
|
| 205 |
+
may be construed as permission to assert or imply that You
|
| 206 |
+
are, or that Your use of the Licensed Material is, connected
|
| 207 |
+
with, or sponsored, endorsed, or granted official status by,
|
| 208 |
+
the Licensor or others designated to receive attribution as
|
| 209 |
+
provided in Section 3(a)(1)(A)(i).
|
| 210 |
+
|
| 211 |
+
b. Other rights.
|
| 212 |
+
|
| 213 |
+
1. Moral rights, such as the right of integrity, are not
|
| 214 |
+
licensed under this Public License, nor are publicity,
|
| 215 |
+
privacy, and/or other similar personality rights; however, to
|
| 216 |
+
the extent possible, the Licensor waives and/or agrees not to
|
| 217 |
+
assert any such rights held by the Licensor to the limited
|
| 218 |
+
extent necessary to allow You to exercise the Licensed
|
| 219 |
+
Rights, but not otherwise.
|
| 220 |
+
|
| 221 |
+
2. Patent and trademark rights are not licensed under this
|
| 222 |
+
Public License.
|
| 223 |
+
|
| 224 |
+
3. To the extent possible, the Licensor waives any right to
|
| 225 |
+
collect royalties from You for the exercise of the Licensed
|
| 226 |
+
Rights, whether directly or through a collecting society
|
| 227 |
+
under any voluntary or waivable statutory or compulsory
|
| 228 |
+
licensing scheme. In all other cases the Licensor expressly
|
| 229 |
+
reserves any right to collect such royalties.
|
| 230 |
+
|
| 231 |
+
|
| 232 |
+
Section 3 -- License Conditions.
|
| 233 |
+
|
| 234 |
+
Your exercise of the Licensed Rights is expressly made subject to the
|
| 235 |
+
following conditions.
|
| 236 |
+
|
| 237 |
+
a. Attribution.
|
| 238 |
+
|
| 239 |
+
1. If You Share the Licensed Material (including in modified
|
| 240 |
+
form), You must:
|
| 241 |
+
|
| 242 |
+
a. retain the following if it is supplied by the Licensor
|
| 243 |
+
with the Licensed Material:
|
| 244 |
+
|
| 245 |
+
i. identification of the creator(s) of the Licensed
|
| 246 |
+
Material and any others designated to receive
|
| 247 |
+
attribution, in any reasonable manner requested by
|
| 248 |
+
the Licensor (including by pseudonym if
|
| 249 |
+
designated);
|
| 250 |
+
|
| 251 |
+
ii. a copyright notice;
|
| 252 |
+
|
| 253 |
+
iii. a notice that refers to this Public License;
|
| 254 |
+
|
| 255 |
+
iv. a notice that refers to the disclaimer of
|
| 256 |
+
warranties;
|
| 257 |
+
|
| 258 |
+
v. a URI or hyperlink to the Licensed Material to the
|
| 259 |
+
extent reasonably practicable;
|
| 260 |
+
|
| 261 |
+
b. indicate if You modified the Licensed Material and
|
| 262 |
+
retain an indication of any previous modifications; and
|
| 263 |
+
|
| 264 |
+
c. indicate the Licensed Material is licensed under this
|
| 265 |
+
Public License, and include the text of, or the URI or
|
| 266 |
+
hyperlink to, this Public License.
|
| 267 |
+
|
| 268 |
+
2. You may satisfy the conditions in Section 3(a)(1) in any
|
| 269 |
+
reasonable manner based on the medium, means, and context in
|
| 270 |
+
which You Share the Licensed Material. For example, it may be
|
| 271 |
+
reasonable to satisfy the conditions by providing a URI or
|
| 272 |
+
hyperlink to a resource that includes the required
|
| 273 |
+
information.
|
| 274 |
+
|
| 275 |
+
3. If requested by the Licensor, You must remove any of the
|
| 276 |
+
information required by Section 3(a)(1)(A) to the extent
|
| 277 |
+
reasonably practicable.
|
| 278 |
+
|
| 279 |
+
4. If You Share Adapted Material You produce, the Adapter's
|
| 280 |
+
License You apply must not prevent recipients of the Adapted
|
| 281 |
+
Material from complying with this Public License.
|
| 282 |
+
|
| 283 |
+
|
| 284 |
+
Section 4 -- Sui Generis Database Rights.
|
| 285 |
+
|
| 286 |
+
Where the Licensed Rights include Sui Generis Database Rights that
|
| 287 |
+
apply to Your use of the Licensed Material:
|
| 288 |
+
|
| 289 |
+
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
| 290 |
+
to extract, reuse, reproduce, and Share all or a substantial
|
| 291 |
+
portion of the contents of the database;
|
| 292 |
+
|
| 293 |
+
b. if You include all or a substantial portion of the database
|
| 294 |
+
contents in a database in which You have Sui Generis Database
|
| 295 |
+
Rights, then the database in which You have Sui Generis Database
|
| 296 |
+
Rights (but not its individual contents) is Adapted Material; and
|
| 297 |
+
|
| 298 |
+
c. You must comply with the conditions in Section 3(a) if You Share
|
| 299 |
+
all or a substantial portion of the contents of the database.
|
| 300 |
+
|
| 301 |
+
For the avoidance of doubt, this Section 4 supplements and does not
|
| 302 |
+
replace Your obligations under this Public License where the Licensed
|
| 303 |
+
Rights include other Copyright and Similar Rights.
|
| 304 |
+
|
| 305 |
+
|
| 306 |
+
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
| 307 |
+
|
| 308 |
+
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
| 309 |
+
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
| 310 |
+
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
| 311 |
+
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
| 312 |
+
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
| 313 |
+
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
| 314 |
+
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
| 315 |
+
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
| 316 |
+
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
| 317 |
+
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
| 318 |
+
|
| 319 |
+
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
| 320 |
+
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
| 321 |
+
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
| 322 |
+
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
| 323 |
+
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
| 324 |
+
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
| 325 |
+
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
| 326 |
+
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
| 327 |
+
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
| 328 |
+
|
| 329 |
+
c. The disclaimer of warranties and limitation of liability provided
|
| 330 |
+
above shall be interpreted in a manner that, to the extent
|
| 331 |
+
possible, most closely approximates an absolute disclaimer and
|
| 332 |
+
waiver of all liability.
|
| 333 |
+
|
| 334 |
+
|
| 335 |
+
Section 6 -- Term and Termination.
|
| 336 |
+
|
| 337 |
+
a. This Public License applies for the term of the Copyright and
|
| 338 |
+
Similar Rights licensed here. However, if You fail to comply with
|
| 339 |
+
this Public License, then Your rights under this Public License
|
| 340 |
+
terminate automatically.
|
| 341 |
+
|
| 342 |
+
b. Where Your right to use the Licensed Material has terminated under
|
| 343 |
+
Section 6(a), it reinstates:
|
| 344 |
+
|
| 345 |
+
1. automatically as of the date the violation is cured, provided
|
| 346 |
+
it is cured within 30 days of Your discovery of the
|
| 347 |
+
violation; or
|
| 348 |
+
|
| 349 |
+
2. upon express reinstatement by the Licensor.
|
| 350 |
+
|
| 351 |
+
For the avoidance of doubt, this Section 6(b) does not affect any
|
| 352 |
+
right the Licensor may have to seek remedies for Your violations
|
| 353 |
+
of this Public License.
|
| 354 |
+
|
| 355 |
+
c. For the avoidance of doubt, the Licensor may also offer the
|
| 356 |
+
Licensed Material under separate terms or conditions or stop
|
| 357 |
+
distributing the Licensed Material at any time; however, doing so
|
| 358 |
+
will not terminate this Public License.
|
| 359 |
+
|
| 360 |
+
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
| 361 |
+
License.
|
| 362 |
+
|
| 363 |
+
|
| 364 |
+
Section 7 -- Other Terms and Conditions.
|
| 365 |
+
|
| 366 |
+
a. The Licensor shall not be bound by any additional or different
|
| 367 |
+
terms or conditions communicated by You unless expressly agreed.
|
| 368 |
+
|
| 369 |
+
b. Any arrangements, understandings, or agreements regarding the
|
| 370 |
+
Licensed Material not stated herein are separate from and
|
| 371 |
+
independent of the terms and conditions of this Public License.
|
| 372 |
+
|
| 373 |
+
|
| 374 |
+
Section 8 -- Interpretation.
|
| 375 |
+
|
| 376 |
+
a. For the avoidance of doubt, this Public License does not, and
|
| 377 |
+
shall not be interpreted to, reduce, limit, restrict, or impose
|
| 378 |
+
conditions on any use of the Licensed Material that could lawfully
|
| 379 |
+
be made without permission under this Public License.
|
| 380 |
+
|
| 381 |
+
b. To the extent possible, if any provision of this Public License is
|
| 382 |
+
deemed unenforceable, it shall be automatically reformed to the
|
| 383 |
+
minimum extent necessary to make it enforceable. If the provision
|
| 384 |
+
cannot be reformed, it shall be severed from this Public License
|
| 385 |
+
without affecting the enforceability of the remaining terms and
|
| 386 |
+
conditions.
|
| 387 |
+
|
| 388 |
+
c. No term or condition of this Public License will be waived and no
|
| 389 |
+
failure to comply consented to unless expressly agreed to by the
|
| 390 |
+
Licensor.
|
| 391 |
+
|
| 392 |
+
d. Nothing in this Public License constitutes or may be interpreted
|
| 393 |
+
as a limitation upon, or waiver of, any privileges and immunities
|
| 394 |
+
that apply to the Licensor or You, including from the legal
|
| 395 |
+
processes of any jurisdiction or authority.
|
| 396 |
+
|
| 397 |
+
|
| 398 |
+
=======================================================================
|
| 399 |
+
|
| 400 |
+
Creative Commons is not a party to its public
|
| 401 |
+
licenses. Notwithstanding, Creative Commons may elect to apply one of
|
| 402 |
+
its public licenses to material it publishes and in those instances
|
| 403 |
+
will be considered the “Licensor.” The text of the Creative Commons
|
| 404 |
+
public licenses is dedicated to the public domain under the CC0 Public
|
| 405 |
+
Domain Dedication. Except for the limited purpose of indicating that
|
| 406 |
+
material is shared under a Creative Commons public license or as
|
| 407 |
+
otherwise permitted by the Creative Commons policies published at
|
| 408 |
+
creativecommons.org/policies, Creative Commons does not authorize the
|
| 409 |
+
use of the trademark "Creative Commons" or any other trademark or logo
|
| 410 |
+
of Creative Commons without its prior written consent including,
|
| 411 |
+
without limitation, in connection with any unauthorized modifications
|
| 412 |
+
to any of its public licenses or any other arrangements,
|
| 413 |
+
understandings, or agreements concerning use of licensed material. For
|
| 414 |
+
the avoidance of doubt, this paragraph does not form part of the
|
| 415 |
+
public licenses.
|
| 416 |
+
|
| 417 |
+
Creative Commons may be contacted at creativecommons.org.
|
| 418 |
+
|
| 419 |
+
-----------------------------------------------------------------------
|
| 420 |
+
|
| 421 |
+
Third-party notice: intfloat/multilingual-e5-large
|
| 422 |
+
|
| 423 |
+
Base model: https://huggingface.co/intfloat/multilingual-e5-large
|
| 424 |
+
License: MIT
|
| 425 |
+
|
| 426 |
+
MIT License
|
| 427 |
+
|
| 428 |
+
Copyright (c) Microsoft Corporation.
|
| 429 |
+
|
| 430 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 431 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 432 |
+
in the Software without restriction, including without limitation the rights
|
| 433 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 434 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 435 |
+
furnished to do so, subject to the following conditions:
|
| 436 |
+
|
| 437 |
+
The above copyright notice and this permission notice shall be included in all
|
| 438 |
+
copies or substantial portions of the Software.
|
| 439 |
+
|
| 440 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 441 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 442 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 443 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 444 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 445 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 446 |
+
SOFTWARE.
|
README.md
ADDED
|
@@ -0,0 +1,425 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
language:
|
| 3 |
+
- hno
|
| 4 |
+
- hnd
|
| 5 |
+
license: cc-by-4.0
|
| 6 |
+
library_name: sentence-transformers
|
| 7 |
+
pipeline_tag: sentence-similarity
|
| 8 |
+
base_model: intfloat/multilingual-e5-large
|
| 9 |
+
tags:
|
| 10 |
+
- sentence-transformers
|
| 11 |
+
- feature-extraction
|
| 12 |
+
- sentence-similarity
|
| 13 |
+
- hindko
|
| 14 |
+
- embeddings
|
| 15 |
+
- low-resource
|
| 16 |
+
- urdu-script
|
| 17 |
+
- perso-arabic
|
| 18 |
+
model-index:
|
| 19 |
+
- name: hindko-embeddings
|
| 20 |
+
results:
|
| 21 |
+
- task:
|
| 22 |
+
type: Retrieval
|
| 23 |
+
dataset:
|
| 24 |
+
name: HindkoEmbedBench v1.0 HeadlineRetrieval
|
| 25 |
+
type: HindkoEmbedBench-HeadlineRetrieval
|
| 26 |
+
split: test
|
| 27 |
+
metrics:
|
| 28 |
+
- type: ndcg_at_10
|
| 29 |
+
name: nDCG@10
|
| 30 |
+
value: 0.6372
|
| 31 |
+
- type: recall_at_1
|
| 32 |
+
name: Recall@1
|
| 33 |
+
value: 0.5625
|
| 34 |
+
- type: recall_at_10
|
| 35 |
+
name: Recall@10
|
| 36 |
+
value: 0.7125
|
| 37 |
+
- task:
|
| 38 |
+
type: Retrieval
|
| 39 |
+
dataset:
|
| 40 |
+
name: HindkoEmbedBench v1.0 BookTitleRetrieval
|
| 41 |
+
type: HindkoEmbedBench-BookTitleRetrieval
|
| 42 |
+
split: test
|
| 43 |
+
metrics:
|
| 44 |
+
- type: ndcg_at_10
|
| 45 |
+
name: nDCG@10
|
| 46 |
+
value: 0.3460
|
| 47 |
+
- type: recall_at_1
|
| 48 |
+
name: Recall@1
|
| 49 |
+
value: 0.1548
|
| 50 |
+
- type: recall_at_10
|
| 51 |
+
name: Recall@10
|
| 52 |
+
value: 0.4494
|
| 53 |
+
- type: mrr_at_10
|
| 54 |
+
name: MRR@10
|
| 55 |
+
value: 0.3608
|
| 56 |
+
- task:
|
| 57 |
+
type: Retrieval
|
| 58 |
+
dataset:
|
| 59 |
+
name: HindkoEmbedBench v1.0 PassageContinuation
|
| 60 |
+
type: HindkoEmbedBench-PassageContinuation
|
| 61 |
+
split: test
|
| 62 |
+
metrics:
|
| 63 |
+
- type: ndcg_at_10
|
| 64 |
+
name: nDCG@10
|
| 65 |
+
value: 0.8756
|
| 66 |
+
- task:
|
| 67 |
+
type: Classification
|
| 68 |
+
dataset:
|
| 69 |
+
name: HindkoEmbedBench v1.0 VerseProseClassification
|
| 70 |
+
type: HindkoEmbedBench-VerseProseClassification
|
| 71 |
+
split: test
|
| 72 |
+
metrics:
|
| 73 |
+
- type: f1
|
| 74 |
+
name: macro-F1
|
| 75 |
+
value: 0.9801
|
| 76 |
+
- task:
|
| 77 |
+
type: Clustering
|
| 78 |
+
dataset:
|
| 79 |
+
name: HindkoEmbedBench v1.0 BookClustering
|
| 80 |
+
type: HindkoEmbedBench-BookClustering
|
| 81 |
+
split: test
|
| 82 |
+
metrics:
|
| 83 |
+
- type: v_measure
|
| 84 |
+
name: V-measure
|
| 85 |
+
value: 0.8566
|
| 86 |
+
---
|
| 87 |
+
|
| 88 |
+
# Hindko Embeddings
|
| 89 |
+
|
| 90 |
+
> **License: [CC BY 4.0](LICENSE)** for this model's weights and files. The base model, intfloat/multilingual-e5-large, is MIT-licensed; its notice is kept in [`LICENSE`](LICENSE). See [License](#license).
|
| 91 |
+
|
| 92 |
+
A sentence-embedding model for **Hindko** (Northern `hno` and Southern `hnd`), the Indo-Aryan language of Peshawar, Hazara and Kohat in Khyber Pakhtunkhwa, Pakistan, written in Urdu (Perso-Arabic) script. It turns a Hindko headline, sentence, verse or passage into a vector, so that texts about the same thing end up close together: for search, retrieval for RAG, similarity, clustering and classification. It is [intfloat/multilingual-e5-large](https://huggingface.co/intfloat/multilingual-e5-large) fine-tuned on 41,533 training pairs from a Hindko corpus (39,517 of them from Hindko-variety records), and to our knowledge it is the first embedding model trained for Hindko.
|
| 93 |
+
|
| 94 |
+
On the held-out test split of **HindkoEmbedBench v1.0**, the five-task benchmark built for this project (first used in round 1, for our earlier model), it scores **0.7391** overall. A character n-gram TF-IDF baseline scores 0.6864, and the best public embedding model tested, bge-m3, scores 0.6332 at the same 512-token length. The model is ahead of TF-IDF on four of the five tasks and **behind it on one**: finding a book passage from its table-of-contents title (see [Limitations](#limitations-and-bias)).
|
| 95 |
+
|
| 96 |
+
## At a glance
|
| 97 |
+
|
| 98 |
+
| | |
|
| 99 |
+
|---|---|
|
| 100 |
+
| **Type** | Sentence-transformers bi-encoder: transformer encoder, mean pooling, L2-normalized output |
|
| 101 |
+
| **Base model** | [intfloat/multilingual-e5-large](https://huggingface.co/intfloat/multilingual-e5-large) (MIT), 560M parameters; its XLM-RoBERTa tokenizer is unchanged |
|
| 102 |
+
| **Output** | 1,024-dimensional vectors; compare with cosine similarity (dot product of normalized vectors) |
|
| 103 |
+
| **Input length** | `max_seq_length` 512 tokens; longer input is truncated |
|
| 104 |
+
| **Prefixes** | `query: ` for queries and for similarity, clustering and classification; `passage: ` for documents to be retrieved ([details](#prefixes)) |
|
| 105 |
+
| **Library** | sentence-transformers 6.0 or later with transformers 5.x (saved with sentence-transformers 6.1.0 and transformers 5.3.0); older versions may not load the saved configuration |
|
| 106 |
+
| **Language** | Hindko in Urdu script (`hno`, `hnd`). Not evaluated on Romanized Hindko or other languages |
|
| 107 |
+
| **Training data** | 41,533 pairs (87,176 distinct texts) from the train split of a Hindko corpus of newspapers, books and web pages, with 23,061 mined hard negatives |
|
| 108 |
+
| **Test score** | **0.7391** overall; TF-IDF 0.6864, bge-m3 0.6332, our round-1 model 0.6923 |
|
| 109 |
+
| **Known weak spot** | Book-title retrieval: 0.3460 nDCG@10 on test, below TF-IDF (0.3756) and bge-m3 (0.3778) |
|
| 110 |
+
| **Weights** | float16 safetensors, about 1,068 MB: the same weights that were benchmarked |
|
| 111 |
+
| **Version** | 1.0.0, 2026-10-01 |
|
| 112 |
+
| **Sibling project** | [Hindko Tokenizer](https://huggingface.co/junaid008/hindko-tokenizer) ([GitHub](https://github.com/junaidaslam2006/Hindko-Tokenizer)). This model does **not** use it; it keeps its base model's tokenizer |
|
| 113 |
+
| **Code** | The benchmark and the training code will be released |
|
| 114 |
+
|
| 115 |
+
## Highlights
|
| 116 |
+
|
| 117 |
+
- **Highest overall test score of all models tested**: 0.7391, against 0.6864 for TF-IDF (+0.0527), 0.6332 for bge-m3 (+0.1059) and 0.5977 for its own base model without fine-tuning (+0.1414).
|
| 118 |
+
- **Large gains on passage tasks**: continuation retrieval 0.8756 nDCG@10 (TF-IDF 0.7899, bge-m3 0.7174) and book clustering 0.8566 V-measure (TF-IDF 0.6895, bge-m3 0.5168).
|
| 119 |
+
- **Better than our round-1 model** (0.6923 on test) on four of five tasks; slightly lower on verse/prose classification (0.9801 vs 0.9827).
|
| 120 |
+
- **Chosen on dev only**, by a rule fixed in advance; this model was scored on test once, after the choice.
|
| 121 |
+
- **Weak spot**: book-title retrieval, where TF-IDF and bge-m3 score higher on test (28 queries) and TF-IDF scores higher on dev (262 queries); on dev the model is also narrowly behind TF-IDF on verse/prose (0.9406 vs 0.9463).
|
| 122 |
+
|
| 123 |
+

|
| 124 |
+
|
| 125 |
+
## Usage
|
| 126 |
+
|
| 127 |
+
```bash
|
| 128 |
+
pip install -U "sentence-transformers>=6.0"
|
| 129 |
+
```
|
| 130 |
+
|
| 131 |
+
### Search (retrieval)
|
| 132 |
+
|
| 133 |
+
```python
|
| 134 |
+
from sentence_transformers import SentenceTransformer
|
| 135 |
+
|
| 136 |
+
model = SentenceTransformer("junaid008/hindko-embeddings")
|
| 137 |
+
if model.device.type == "cpu":
|
| 138 |
+
model = model.float() # weights are stored in float16; use float32 on a CPU
|
| 139 |
+
|
| 140 |
+
query = "query: ڈرامے دی پیدائش"
|
| 141 |
+
passages = [
|
| 142 |
+
"passage: ایہہ بہت کہٹ لوک جانڑدین کہ ڈرامے دی پیدائش کسراں تے کتھے ہوئی آئی۔",
|
| 143 |
+
"passage: اج اساں اگر آپڑیں بزرگاں دی انہاں گلاں تے غور نہ کیتا تے پچھتاوے دے سوا کج ہتھ نہ آسی۔",
|
| 144 |
+
"passage: اسی طراں خیبر پختونخوا اچ بولی جانڑیں ولی دیگر زباناں دے ادب و ثقافت دی بی نمائندگی کیتی گئی اَئی۔",
|
| 145 |
+
]
|
| 146 |
+
|
| 147 |
+
q = model.encode([query], normalize_embeddings=True)
|
| 148 |
+
p = model.encode(passages, normalize_embeddings=True)
|
| 149 |
+
scores = model.similarity(q, p) # cosine similarity, shape (1, 3); higher = more relevant
|
| 150 |
+
ranking = scores[0].argsort(descending=True)
|
| 151 |
+
```
|
| 152 |
+
|
| 153 |
+
### Similarity, clustering and classification
|
| 154 |
+
|
| 155 |
+
Use `query: ` on every text when the texts play the same role:
|
| 156 |
+
|
| 157 |
+
```python
|
| 158 |
+
sentences = [
|
| 159 |
+
"query: ایہہ بہت کہٹ لوک جانڑدین کہ ڈرامے دی پیدائش کسراں تے کتھے ہوئی آئی۔",
|
| 160 |
+
"query: اج اساں اگر آپڑیں بزرگاں دی انہاں گلاں تے غور نہ کیتا تے پچھتاوے دے سوا کج ہتھ نہ آسی۔",
|
| 161 |
+
"query: اسی طراں خیبر پختونخوا اچ بولی جانڑیں ولی دیگر زباناں دے ادب و ثقافت دی بی نمائندگی کیتی گئی اَئی۔",
|
| 162 |
+
]
|
| 163 |
+
emb = model.encode(sentences, normalize_embeddings=True)
|
| 164 |
+
sim = model.similarity(emb, emb) # 3 x 3 cosine-similarity matrix
|
| 165 |
+
```
|
| 166 |
+
|
| 167 |
+
The embeddings can be fed to any clustering or classification method. The benchmark uses k-means and logistic regression from scikit-learn on these normalized vectors. Use the scores to rank or group texts; they are not calibrated probabilities, so set any threshold on your own data.
|
| 168 |
+
|
| 169 |
+
The example sentences are from the held-out test split of the Hindko Tokenizer, and they also occur in HindkoEmbedBench test documents; they were already published in the tokenizer card. Approximate meanings: (1) "Very few people know how and where drama was born." (2) "If we do not reflect on these words of our elders today, we will be left with nothing but regret." (3) "In the same way, the literature and culture of the other languages spoken in Khyber Pakhtunkhwa were also represented." The query means "the birth of drama".
|
| 170 |
+
|
| 171 |
+
### Prefixes
|
| 172 |
+
|
| 173 |
+
The model was trained and evaluated with the e5 prefixes below; results without them were not measured, so keep them.
|
| 174 |
+
|
| 175 |
+
| Text | Prefix |
|
| 176 |
+
|---|---|
|
| 177 |
+
| Search query, headline, title, first line of a poem: anything used to look something up | `query: ` |
|
| 178 |
+
| Document, article, passage or poem to be found | `passage: ` |
|
| 179 |
+
| Both sides of a similarity comparison; texts to cluster or classify | `query: ` |
|
| 180 |
+
|
| 181 |
+
In training, title, verse, prose-sentence, headline and continuation pairs used `query: ` for the anchor and `passage: ` for the positive and the negatives; pairs of neighbouring chunks used `query: ` on both sides. The benchmark uses the same scheme.
|
| 182 |
+
|
| 183 |
+
Write the prefix into the text and call `model.encode`, as in the examples. `encode_query()` and `encode_document()` do **not** add these prefixes for this model.
|
| 184 |
+
|
| 185 |
+
### Normalize input first
|
| 186 |
+
|
| 187 |
+
Training and benchmark text was put in one canonical form: Unicode NFC, invisible and control characters removed, spaces collapsed, Arabic presentation forms mapped to letters, and Arabic-keyboard YEH/KAF folded where the word is provably Urdu or Hindko spelling. The Hindko Tokenizer repository ships a self-contained `normalize()` that produces this form:
|
| 188 |
+
|
| 189 |
+
```python
|
| 190 |
+
import os, sys
|
| 191 |
+
from huggingface_hub import hf_hub_download
|
| 192 |
+
|
| 193 |
+
qs = hf_hub_download("junaid008/hindko-tokenizer", "examples/quickstart.py")
|
| 194 |
+
sys.path.insert(0, os.path.dirname(qs))
|
| 195 |
+
from quickstart import normalize
|
| 196 |
+
|
| 197 |
+
raw_text = "ایہہ بہت کہٹ لوک جانڑدین" # any Hindko input
|
| 198 |
+
text = normalize(raw_text) # here: the double space is collapsed
|
| 199 |
+
```
|
| 200 |
+
|
| 201 |
+
### Practical notes
|
| 202 |
+
|
| 203 |
+
- **Length.** Input is cut at 512 tokens. For long documents, split them into passages (for example at sentence boundaries) and embed each one.
|
| 204 |
+
- **Precision.** The weights are float16, and all benchmark numbers were measured with them on a GPU in float16. On a CPU, convert to float32 as shown above.
|
| 205 |
+
- **Normalization of vectors.** Pass `normalize_embeddings=True`, as the benchmark did; cosine similarity and dot product then agree.
|
| 206 |
+
|
| 207 |
+
## HindkoEmbedBench v1.0
|
| 208 |
+
|
| 209 |
+
To our knowledge there was no benchmark for Hindko text embeddings, so one was built for this project (first used in round 1). It has five tasks in the style of MTEB, each with a **dev** version (used for model selection) and a **test** version (scored once per model, after selection). It was built **automatically from corpus metadata**: headlines and their articles, table-of-contents titles and their passages, the verse/prose label of book passages, and the book each passage comes from. No human relevance judgments were collected.
|
| 210 |
+
|
| 211 |
+
| Task | Type | Main metric | Dev | Test |
|
| 212 |
+
|---|---|---|---|---|
|
| 213 |
+
| HeadlineRetrieval | retrieval: newspaper headline or web page title finds its article | nDCG@10 | 85 queries / 784 docs | 80 queries / 517 docs |
|
| 214 |
+
| BookTitleRetrieval | retrieval: table-of-contents title (often a poem's first line) finds its passage(s) | nDCG@10 | 262 queries / 784 docs | 28 queries (57 relevant) / 517 docs |
|
| 215 |
+
| PassageContinuation | retrieval: first half of a passage finds its second half | nDCG@10 | 416 queries / 416 docs | 360 queries / 360 docs |
|
| 216 |
+
| VerseProseClassification | logistic regression on frozen embeddings | macro-F1 | 1,600 train / 297 eval | 1,600 train / 157 eval |
|
| 217 |
+
| BookClustering | k-means, k = number of books | V-measure | 355 passages, 8 books | 176 passages, 5 books |
|
| 218 |
+
|
| 219 |
+
**Overall score** = unweighted mean of the five main metrics.
|
| 220 |
+
|
| 221 |
+
**How it was built.**
|
| 222 |
+
- **Group-disjoint, leak-checked splits.** Whole newspaper editions, books and web sites sit on one side of the split. The benchmark uses the same record-level splits as the Hindko Tokenizer, published as [`split_manifest.jsonl`](https://github.com/junaidaslam2006/Hindko-Tokenizer/blob/main/tokenizer/splits/split_manifest.jsonl) (sha256 `76582d3a1e0afefe…`). Only Hindko-variety records are used.
|
| 223 |
+
- **Shortcut filters.** A record's own title is stripped from its text; generic or repeated titles, titles that appear verbatim in the target, and near-duplicate documents are removed. Documents are cut at a sentence boundary at or below 3,000 characters. One known artifact remains: book-title relevant passages rarely start with a short genre label line (a line reading only "ghazal" or "naat", for example), while about 31 % of test book documents (5 % on dev) do, so a model could gain by ranking such documents low. Our training data strips these lines from both positives and mined negatives, so training does not reward this cue.
|
| 224 |
+
- **Classification and clustering** follow the MTEB protocol: 10 logistic-regression runs on 256 examples per label drawn from a train-split pool of 1,600 passages; 10 k-means runs. The train pool and the evaluation books are disjoint.
|
| 225 |
+
- **Frozen.** Every task file is hashed, and the harness refuses to run if a file changes.
|
| 226 |
+
|
| 227 |
+
**Release status.** The benchmark data contains newspaper and book text and is **not released yet**. This card describes it; the benchmark code will be released with the training code.
|
| 228 |
+
|
| 229 |
+
## Results
|
| 230 |
+
|
| 231 |
+
All models were run with the same harness: sentence-transformers, `normalize_embeddings=True`, cosine scoring, each model with its own recommended prefixes. Neural models were run at `max_seq_length` 512 in float16, except the two round-1 models (256 tokens, float32). Full numbers: [`eval/results.csv`](eval/results.csv).
|
| 232 |
+
|
| 233 |
+
### Test split (scored once per model, after selection)
|
| 234 |
+
|
| 235 |
+
| Model | Tokens | Overall | Headline nDCG@10 | BookTitle nDCG@10 | Continuation nDCG@10 | Verse/prose macro-F1 | Clustering V-measure |
|
| 236 |
+
|---|---:|---:|---:|---:|---:|---:|---:|
|
| 237 |
+
| **Hindko Embeddings (this model)** | 512 | **0.7391** | **0.6372** | 0.3460 | **0.8756** | 0.9801 | **0.8566** |
|
| 238 |
+
| Round-1 e5-small fine-tune (ours) | 256 | 0.7197 | 0.6091 | 0.3664 | 0.8314 | 0.9736 | 0.8177 |
|
| 239 |
+
| Round-1 model, e5-base fine-tune (ours) | 256 | 0.6923 | 0.6097 | 0.2740 | 0.8340 | **0.9827** | 0.7612 |
|
| 240 |
+
| Round-2 e5-base fine-tune (ours, runner-up on dev) | 512 | 0.6919 | 0.6027 | 0.2422 | 0.8350 | 0.9818 | 0.7979 |
|
| 241 |
+
| TF-IDF char 2-4-gram (lexical reference) | n/a | 0.6864 | 0.6173 | 0.3756 | 0.7899 | 0.9597 | 0.6895 |
|
| 242 |
+
| BAAI/bge-m3 | 512 | 0.6332 | 0.5960 | **0.3778** | 0.7174 | 0.9578 | 0.5168 |
|
| 243 |
+
| intfloat/multilingual-e5-large (base model) | 512 | 0.5977 | 0.5886 | 0.3122 | 0.6706 | 0.9413 | 0.4758 |
|
| 244 |
+
| intfloat/multilingual-e5-small | 512 | 0.5619 | 0.5381 | 0.2934 | 0.5664 | 0.9197 | 0.4918 |
|
| 245 |
+
| Qwen/Qwen3-Embedding-0.6B | 512 | 0.5576 | 0.5634 | 0.2784 | 0.6186 | 0.9051 | 0.4227 |
|
| 246 |
+
| intfloat/multilingual-e5-base | 512 | 0.5532 | 0.5626 | 0.2776 | 0.6139 | 0.8540 | 0.4580 |
|
| 247 |
+
| sentence-transformers/LaBSE | 512 | 0.5314 | 0.5064 | 0.1608 | 0.5383 | 0.9616 | 0.4899 |
|
| 248 |
+
| sentence-transformers/paraphrase-multilingual-mpnet-base-v2 | 512 | 0.4428 | 0.3399 | 0.0815 | 0.5030 | 0.9018 | 0.3879 |
|
| 249 |
+
|
| 250 |
+
Best value per column in bold. The public models are untuned. They were first run at 256 tokens (float32) in round 1 and re-run at 512 tokens (float16) for this comparison, so length and precision changed together. On test this raised six of the seven (bge-m3: 0.6185 to 0.6332; multilingual-e5-large: 0.5605 to 0.5977) and left paraphrase-multilingual-mpnet unchanged (0.4429 to 0.4428), so the 512-token numbers are the stronger comparison overall. On dev, LaBSE (0.5200 to 0.5139) and multilingual-e5-small (0.5371 to 0.5353) fell slightly.
|
| 251 |
+
|
| 252 |
+
Of our own models, only this model and the round-2 runner-up were scored on test in round 2; the two round-1 models were scored on test in round 1. The round-1 e5-small model scores second on test (0.7197) but was not chosen in round 1, because its dev score was lower.
|
| 253 |
+
|
| 254 |
+
### Dev split (used for model selection)
|
| 255 |
+
|
| 256 |
+
| Model | Tokens | Overall | Headline | BookTitle | Continuation | Verse/prose | Clustering |
|
| 257 |
+
|---|---:|---:|---:|---:|---:|---:|---:|
|
| 258 |
+
| **Hindko Embeddings (this model, `r2-e5l`)** | 512 | **0.7117** | 0.6357 | 0.4257 | **0.8308** | 0.9406 | 0.7258 |
|
| 259 |
+
| Round-2 e5-base fine-tune (`r2-e5b`) | 512 | 0.7079 | 0.6006 | 0.4464 | 0.8176 | 0.9411 | **0.7339** |
|
| 260 |
+
| Round-2 e5-base, no mined negatives or book blocks (`r2-e5b-plain`) | 512 | 0.7066 | 0.5941 | 0.4408 | 0.8295 | 0.9453 | 0.7234 |
|
| 261 |
+
| Round-2 e5-small fine-tune (`r2-e5s`) | 512 | 0.7039 | 0.6191 | 0.4358 | 0.8094 | **0.9480** | 0.7070 |
|
| 262 |
+
| Round-2 bge-m3 fine-tune (`r2-bgem3`) | 512 | 0.7008 | **0.6459** | 0.4435 | 0.8246 | 0.9429 | 0.6470 |
|
| 263 |
+
| Round-1 model, e5-base fine-tune | 256 | 0.6851 | 0.6299 | 0.3288 | 0.8081 | 0.9432 | 0.7157 |
|
| 264 |
+
| Round-1 e5-small fine-tune | 256 | 0.6700 | 0.6193 | 0.2778 | 0.7943 | 0.9382 | 0.7204 |
|
| 265 |
+
| TF-IDF char 2-4-gram | n/a | 0.6667 | 0.6049 | **0.4594** | 0.7655 | 0.9463 | 0.5573 |
|
| 266 |
+
| BAAI/bge-m3 | 512 | 0.5923 | 0.6183 | 0.2443 | 0.6617 | 0.9363 | 0.5011 |
|
| 267 |
+
| intfloat/multilingual-e5-large | 512 | 0.5872 | 0.6028 | 0.2004 | 0.6524 | 0.9425 | 0.5379 |
|
| 268 |
+
| intfloat/multilingual-e5-base | 512 | 0.5737 | 0.5728 | 0.1827 | 0.6293 | 0.9381 | 0.5457 |
|
| 269 |
+
| Qwen/Qwen3-Embedding-0.6B | 512 | 0.5449 | 0.5327 | 0.1735 | 0.6297 | 0.8985 | 0.4902 |
|
| 270 |
+
| intfloat/multilingual-e5-small | 512 | 0.5353 | 0.5467 | 0.1186 | 0.5698 | 0.9311 | 0.5101 |
|
| 271 |
+
| sentence-transformers/LaBSE | 512 | 0.5139 | 0.4165 | 0.2089 | 0.5036 | 0.9455 | 0.4948 |
|
| 272 |
+
| sentence-transformers/paraphrase-multilingual-mpnet-base-v2 | 512 | 0.4280 | 0.2822 | 0.1138 | 0.4360 | 0.8869 | 0.4210 |
|
| 273 |
+
|
| 274 |
+
Same metrics as the test table. On dev this model is ahead of TF-IDF on three of five tasks (headline, continuation, clustering) and behind it on book titles (0.4257 vs 0.4594) and, narrowly, on verse/prose (0.9406 vs 0.9463).
|
| 275 |
+
|
| 276 |
+
### Retrieval details (test)
|
| 277 |
+
|
| 278 |
+
| Model | Headline R@1 | Headline R@10 | Headline nDCG@10, newspaper (72 q) | Headline nDCG@10, web (8 q) | BookTitle R@1 | BookTitle R@10 | BookTitle MRR@10 |
|
| 279 |
+
|---|---:|---:|---:|---:|---:|---:|---:|
|
| 280 |
+
| **This model** | **0.5625** | **0.7125** | **0.6072** | 0.9077 | 0.1548 | 0.4494 | 0.3608 |
|
| 281 |
+
| TF-IDF char 2-4-gram | 0.5500 | 0.6875 | 0.5879 | 0.8827 | 0.1875 | **0.5030** | 0.3579 |
|
| 282 |
+
| BAAI/bge-m3 (512) | 0.5500 | 0.6500 | 0.5581 | 0.9375 | **0.2262** | 0.4286 | **0.4113** |
|
| 283 |
+
| Round-1 model (256) | 0.5375 | 0.6750 | 0.5715 | **0.9539** | 0.1012 | 0.4315 | 0.2731 |
|
| 284 |
+
|
| 285 |
+
R@k is recall at k; a book-title query can have several relevant passages (57 for 28 queries).
|
| 286 |
+
|
| 287 |
+
### Charts
|
| 288 |
+
|
| 289 |
+
The images are in [`benchmarks/`](benchmarks) (3200 x 1800 PNG, free to reuse under the licence) and are drawn from [`eval/results.csv`](eval/results.csv) and [`eval/selection.json`](eval/selection.json) by [`make_charts.py`](make_charts.py).
|
| 290 |
+
|
| 291 |
+

|
| 292 |
+
|
| 293 |
+

|
| 294 |
+
|
| 295 |
+

|
| 296 |
+
|
| 297 |
+

|
| 298 |
+
|
| 299 |
+

|
| 300 |
+
|
| 301 |
+

|
| 302 |
+
|
| 303 |
+
## Training
|
| 304 |
+
|
| 305 |
+
### Data
|
| 306 |
+
|
| 307 |
+
Pairs were built only from the **train split** of a Hindko corpus: issues of the *Weekly Hindkowan* (Peshawar), the *Gandhara Hindko Academy* book series (much of it poetry) and Hindko web pages. Each pair is an anchor and a positive; some rows also carry mined hard negatives.
|
| 308 |
+
|
| 309 |
+
| Dataset | Pair (anchor → positive) | Rows | Mined negatives per row |
|
| 310 |
+
|---|---|---:|---:|
|
| 311 |
+
| title | table-of-contents title → its passage (1,886); first line of a poem → the rest of the poem (2,505) | 4,391 | 3 (2 from the same book, 1 from another book) |
|
| 312 |
+
| verse_ict | one line of a poem → the poem with that line removed (the line is kept in about 10 % of rows) | 2,949 | 1 (same book) |
|
| 313 |
+
| prose_q | headline or web page title → article body (1,585: 1,447 news, 138 web); one sentence → the surrounding text (up to 900 characters) with that sentence removed, though it is kept in about 10 % of rows (5,354) | 6,939 | 1 |
|
| 314 |
+
| continuation | first half of a passage of up to 1,200 characters → second half | 12,904 | 0 |
|
| 315 |
+
| neighbour | a chunk of about 500 characters → the next chunk of the same text | 14,350 | 0 |
|
| 316 |
+
| **Total** | 87,176 distinct texts | **41,533** | **23,061** |
|
| 317 |
+
|
| 318 |
+
- **Sources:** 24,745 rows from books, 14,073 from newspapers and 2,715 from web pages.
|
| 319 |
+
- **Variety:** 39,517 rows come from Hindko-variety records. The title, verse and prose-sentence datasets also use 1,268 Urdu-variety and 748 mixed-variety rows from the same corpus.
|
| 320 |
+
- **Hard negatives** were mined with a character 2-4-gram TF-IDF index fit only on training documents (13,519 documents). A candidate was rejected if it was the same record, in the same near-duplicate cluster or the same chapter, contained the anchor (also in variant spellings), or re-used a large part of the positive.
|
| 321 |
+
|
| 322 |
+
**Leak prevention.**
|
| 323 |
+
- Only train-split records were used, and none from a split group that has dev or test records (230 such train records were excluded).
|
| 324 |
+
- One train book (204 records) was excluded because it is a re-edition of a dev book.
|
| 325 |
+
- Any text with word 8-gram containment of 0.3 or more in any dev or test text was dropped, under two text normalizations. Anchors equal to or close to a dev or test query (character 3-gram Jaccard 0.5 or more), and anchors of 12 or more characters contained in any dev or test text, were dropped as well.
|
| 326 |
+
- A separately implemented audit script (it shares no code with the pair builder) re-checked every row against the split manifest and the frozen benchmark files: **0 violations** in all six checks. The highest remaining 8-gram containment is 0.2973.
|
| 327 |
+
- The tokenizer is the base model's, unchanged; no vocabulary was added.
|
| 328 |
+
|
| 329 |
+
### Recipe
|
| 330 |
+
|
| 331 |
+
- **Loss:** `CachedMultipleNegativesRankingLoss` with scale 20, i.e. temperature 0.05. Every other positive and negative in the batch also serves as a negative.
|
| 332 |
+
- **Batches:** 256 rows, each batch drawn from one dataset. Title and verse rows are drawn in **same-book blocks of 32**, so many in-batch negatives are other poems and chapters of the same book. A conflict rule keeps duplicate texts, two rows from one record or duplicate cluster, two passages of one chapter, and a row whose mined negative is another row's positive out of the same batch.
|
| 333 |
+
- **Hyperparameters:** learning rate 2e-5, 2 epochs, 322 optimizer steps (161 per epoch), linear warmup over 10 % of the steps and linear decay, weight decay 0.01, AdamW, bf16 mixed precision, `max_seq_length` 512, gradient-cache mini-batch 32, seed 20261001.
|
| 334 |
+
- **Hardware:** one NVIDIA A100-SXM4-80GB GPU; 1,620 s of training (27 minutes), 25.4 GB peak memory.
|
| 335 |
+
- **Output:** saved in float16. The dev and test scores of this model were measured from the float16 weights that are published here.
|
| 336 |
+
|
| 337 |
+
**What changed from round 1.** The round-1 model (multilingual-e5-base) was trained on 30,431 pairs (headline, book title, continuation and neighbour pairs) at 256 tokens, with in-batch negatives only. Round 2 added the first-line, verse-line and prose-sentence pairs (4,391 title rows against 1,390 book-title pairs in round 1), mined hard negatives, same-book blocks, 512 tokens and the larger base model.
|
| 338 |
+
|
| 339 |
+
**Ablation.** The same e5-base recipe without mined negatives and same-book blocks (`r2-e5b-plain`) scored 0.7066 on dev against 0.7079 with them: a small difference overall (+0.0013), with gains on headlines (+0.0065), book titles (+0.0056) and clustering (+0.0105), and losses on continuation (-0.0119) and verse/prose (-0.0042). It is one seed on dev, so these differences are within noise.
|
| 340 |
+
|
| 341 |
+
## Model selection protocol
|
| 342 |
+
|
| 343 |
+
1. **The benchmark was frozen first.** Task files are hashed, and the harness refuses to run on changed files.
|
| 344 |
+
2. **Recipe gate.** After the first round-2 run (`r2-e5b`), a gate fixed in advance decided the recipe for the remaining runs: book-title nDCG@10 at least 0.36, overall at least 0.685 and clustering at least 0.68 on dev. It passed (0.4464, 0.7079, 0.7339), so the remaining runs (e5-large, e5-small and bge-m3) were trained with mined negatives and same-book blocks.
|
| 345 |
+
3. **Candidates.** Five round-2 models (e5-small, e5-base, e5-large, bge-m3, and e5-base without mined negatives) were trained on the same pairs. Each was evaluated on dev from its saved float16 weights at 512 tokens. The pool also held the two round-1 models, with their round-1 dev scores (0.6851 and 0.6700).
|
| 346 |
+
4. **Rule, written before any round-2 result:** take the highest dev overall score; among models within 0.003 of it, take the smallest. `r2-e5l` scored 0.7117. The next best, `r2-e5b`, scored 0.7079 (0.0038 lower) and was outside the band, so `r2-e5l` was selected and `r2-e5b` became the runner-up. The selection file was written before any round-2 test result existed.
|
| 347 |
+
5. **Test, once.** The selected model and the runner-up were scored on the test split once. The untuned public models were re-run at 512 tokens after the selection and were never in the pool.
|
| 348 |
+
|
| 349 |
+
The round-2 choice used dev only, and test was scored once per model, after it. Test is not untouched across rounds, though: the round-1 test scores of the public models and of our round-1 models were known when round 2 was planned, and the plan cited them, plus a test-split document-length statistic, when it chose the candidate base models and adopted 512 tokens. No checkpoint, hyperparameter or threshold was chosen on test. The dev scores of the round-2 candidates (0.7008 to 0.7117) differ by about the dev standard error estimated in the training plan (about 0.01), so the choice of e5-large over e5-base is not statistically established on dev. On test the two models moved in different directions: 0.7391 for e5-large and 0.6919 for e5-base.
|
| 350 |
+
|
| 351 |
+
## Intended uses
|
| 352 |
+
|
| 353 |
+
- Semantic search and retrieval over Hindko text in Urdu script, including retrieval for RAG systems.
|
| 354 |
+
- Similarity, clustering and classification features for Hindko documents, verses and sentences.
|
| 355 |
+
- A baseline for research on embeddings for low-resource, Perso-Arabic-script languages.
|
| 356 |
+
|
| 357 |
+
**Out of scope.** Romanized Hindko, speech transcripts, cross-lingual search (for example an English query over Hindko documents) and other languages were not evaluated; the base model's multilingual ability may or may not survive fine-tuning. Do not use similarity scores alone for decisions about people.
|
| 358 |
+
|
| 359 |
+
## Limitations and bias
|
| 360 |
+
|
| 361 |
+
- **Book-title retrieval is a weak spot.** On test, this model scores 0.3460 nDCG@10 against 0.3756 for TF-IDF and 0.3778 for bge-m3; our round-1 e5-small model also scored higher (0.3664). On dev it is also behind TF-IDF (0.4257 vs 0.4594). It also has the lowest dev book-title score of the five round-2 candidates (0.4257, against 0.4358 to 0.4464); it was selected on the overall score. For title or first-line lookup, combine it with a lexical search (hybrid retrieval).
|
| 362 |
+
- **Residual overlap.** The leak filters drop training texts with word 8-gram containment of 0.3 or more in dev or test text. A separate line-level fuzzy check still finds one test book-title query whose relevant passage has at least half of its lines closely matched in train-split newspaper reprints, and 1 to 3 dev book-title queries per book with at least 30 %. These may slightly favour models trained on this corpus on book-title retrieval; this model still scores below TF-IDF there.
|
| 363 |
+
- **Small test sets.** The test split has 80 headline queries, only 28 book-title queries (from 5 books), 157 verse/prose items (the verse class is essentially one book) and 176 clustering passages from 5 books. Differences of a few points on these tasks are within noise. Dev and test are both reported for this reason.
|
| 364 |
+
- **Automatic benchmark.** Relevance comes from metadata (headline to article, contents title to passage, book identity), not from human judgments. A few headlines are attached to the wrong article, and book identity is only a proxy for topic and style.
|
| 365 |
+
- **Domain.** Training and evaluation text is newspaper prose (mostly from one Peshawar weekly), literary books (much of it poetry) and a small amount of web text. Expect weaker results on conversational, social-media, technical or legal text.
|
| 366 |
+
- **Dialect and spelling.** Peshawari and literary spellings dominate; Hazara and other varieties are less represented. Hindko spelling varies (retroflex nasal, harakat, Arabic-keyboard letters). The model was trained on normalized text, so [normalize input](#normalize-input-first) the same way.
|
| 367 |
+
- **Script.** Only Urdu (Perso-Arabic) script was evaluated; Romanized Hindko was not.
|
| 368 |
+
- **Truncation.** Retrieval mostly sees the start of each document: benchmark documents are cut at 3,000 characters and the model reads at most 512 tokens.
|
| 369 |
+
- **Selection noise.** See [Model selection protocol](#model-selection-protocol): the dev margin over the runner-up is smaller than the dev standard error.
|
| 370 |
+
- **Bias.** The model reflects the viewpoints and vocabulary of the published newspapers and books it was trained on, and any biases of its multilingual base model. No bias evaluation was done.
|
| 371 |
+
|
| 372 |
+
## Ethical considerations and privacy
|
| 373 |
+
|
| 374 |
+
- **No training text is included.** The repository holds model weights, configuration and evaluation outputs only.
|
| 375 |
+
- **Provenance.** The training and benchmark texts belong to their publishers and authors (*Weekly Hindkowan*, the *Gandhara Hindko Academy* and web sources). They are not distributed here, and the licence below does not cover them.
|
| 376 |
+
- **Use with care.** Embeddings of personal text can reveal what the text is about. Treat stored embeddings with the same care as the text they come from.
|
| 377 |
+
|
| 378 |
+
## License
|
| 379 |
+
|
| 380 |
+
**[Creative Commons Attribution 4.0 International (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/)** for this model; full text in [`LICENSE`](LICENSE).
|
| 381 |
+
|
| 382 |
+
- You may use, share and adapt the model, including commercially.
|
| 383 |
+
- Give credit: "Hindko Embeddings" by junaid008, with a link to this repository (the citation below is enough).
|
| 384 |
+
- The base model, [intfloat/multilingual-e5-large](https://huggingface.co/intfloat/multilingual-e5-large), is released under the MIT License (Copyright (c) Microsoft Corporation). Its notice is reproduced in [`LICENSE`](LICENSE) and must be kept with copies of the weights.
|
| 385 |
+
- The licence covers the files in this repository. It grants no rights in the texts the model was trained or evaluated on, which are not included.
|
| 386 |
+
|
| 387 |
+
## Citation
|
| 388 |
+
|
| 389 |
+
```bibtex
|
| 390 |
+
@misc{hindko_embeddings_2026,
|
| 391 |
+
title = {Hindko Embeddings: a sentence-embedding model for Hindko},
|
| 392 |
+
author = {junaid008},
|
| 393 |
+
year = {2026},
|
| 394 |
+
version = {1.0.0},
|
| 395 |
+
howpublished = {\url{https://huggingface.co/junaid008/hindko-embeddings}},
|
| 396 |
+
note = {CC BY 4.0. Fine-tuned from intfloat/multilingual-e5-large; selected on the dev split of HindkoEmbedBench v1.0 by a pre-registered rule; test overall 0.7391}
|
| 397 |
+
}
|
| 398 |
+
```
|
| 399 |
+
|
| 400 |
+
Please also cite the base model:
|
| 401 |
+
|
| 402 |
+
```bibtex
|
| 403 |
+
@article{wang2024multilingual,
|
| 404 |
+
title = {Multilingual E5 Text Embeddings: A Technical Report},
|
| 405 |
+
author = {Wang, Liang and Yang, Nan and Huang, Xiaolong and Yang, Linjun and Majumder, Rangan and Wei, Furu},
|
| 406 |
+
journal = {arXiv preprint arXiv:2402.05672},
|
| 407 |
+
year = {2024}
|
| 408 |
+
}
|
| 409 |
+
```
|
| 410 |
+
|
| 411 |
+
## Acknowledgements
|
| 412 |
+
|
| 413 |
+
Heartfelt thanks to the **Chief Minister's Policy Office**, the **Weekly Hindkowan** and the **Gandhara Hindko Board** for supporting this work and sharing the texts that made it possible.
|
| 414 |
+
|
| 415 |
+
This project was built together with **Muhammad Ozair**.
|
| 416 |
+
|
| 417 |
+
## Contact
|
| 418 |
+
|
| 419 |
+
**junaid008** on Hugging Face. Please open a discussion on this repository for questions, errors or clearance matters.
|
| 420 |
+
|
| 421 |
+
## Changelog
|
| 422 |
+
|
| 423 |
+
| Version | Date | Changes |
|
| 424 |
+
|---|---|---|
|
| 425 |
+
| 1.0.0 | 2026-10-01 | First release: multilingual-e5-large fine-tuned on 41,533 pairs from a Hindko corpus (round 2, `r2-e5l`); HindkoEmbedBench v1.0 results, selection record and benchmark images. |
|
benchmarks/00_scorecard.png
ADDED
|
Git LFS Details
|
benchmarks/01_test_overall_all_models.png
ADDED
|
Git LFS Details
|
benchmarks/02_test_per_task.png
ADDED
|
Git LFS Details
|
benchmarks/03_dev_candidates.png
ADDED
|
Git LFS Details
|
benchmarks/04_round1_vs_round2.png
ADDED
|
Git LFS Details
|
benchmarks/05_size_vs_score.png
ADDED
|
Git LFS Details
|
benchmarks/06_booktitle_detail.png
ADDED
|
Git LFS Details
|
config.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"add_cross_attention": false,
|
| 3 |
+
"architectures": [
|
| 4 |
+
"XLMRobertaModel"
|
| 5 |
+
],
|
| 6 |
+
"attention_probs_dropout_prob": 0.1,
|
| 7 |
+
"bos_token_id": 0,
|
| 8 |
+
"classifier_dropout": null,
|
| 9 |
+
"dtype": "float16",
|
| 10 |
+
"eos_token_id": 2,
|
| 11 |
+
"hidden_act": "gelu",
|
| 12 |
+
"hidden_dropout_prob": 0.1,
|
| 13 |
+
"hidden_size": 1024,
|
| 14 |
+
"initializer_range": 0.02,
|
| 15 |
+
"intermediate_size": 4096,
|
| 16 |
+
"is_decoder": false,
|
| 17 |
+
"layer_norm_eps": 1e-05,
|
| 18 |
+
"max_position_embeddings": 514,
|
| 19 |
+
"model_type": "xlm-roberta",
|
| 20 |
+
"num_attention_heads": 16,
|
| 21 |
+
"num_hidden_layers": 24,
|
| 22 |
+
"output_past": true,
|
| 23 |
+
"pad_token_id": 1,
|
| 24 |
+
"position_embedding_type": "absolute",
|
| 25 |
+
"tie_word_embeddings": true,
|
| 26 |
+
"transformers_version": "5.3.0",
|
| 27 |
+
"type_vocab_size": 1,
|
| 28 |
+
"use_cache": false,
|
| 29 |
+
"vocab_size": 250002
|
| 30 |
+
}
|
config_sentence_transformers.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"__version__": {
|
| 3 |
+
"pytorch": "2.11.0+cu128",
|
| 4 |
+
"sentence_transformers": "6.1.0",
|
| 5 |
+
"transformers": "5.3.0"
|
| 6 |
+
},
|
| 7 |
+
"default_prompt_name": null,
|
| 8 |
+
"model_type": "SentenceTransformer",
|
| 9 |
+
"prompts": {
|
| 10 |
+
"document": "",
|
| 11 |
+
"query": ""
|
| 12 |
+
},
|
| 13 |
+
"similarity_fn_name": "cosine"
|
| 14 |
+
}
|
eval/results.csv
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
model,model_id,base_model,kind,role,profile,split,max_seq_length,dtype,overall,HeadlineRetrieval,BookTitleRetrieval,PassageContinuation,VerseProseClassification,BookClustering,HL_R1,HL_R10,HL_news,HL_web,HL_nq,BT_R1,BT_R10,BT_MRR
|
| 2 |
+
LaBSE,sentence-transformers/LaBSE,sentence-transformers/LaBSE,public,baseline,labse,dev,512,float16,0.5139,0.4165,0.2089,0.5036,0.9455,0.4948,0.3176,0.5294,0.4239,0.372,85,0.1412,0.3015,0.181
|
| 3 |
+
LaBSE,sentence-transformers/LaBSE,sentence-transformers/LaBSE,public,baseline,labse,test,512,float16,0.5314,0.5064,0.1608,0.5383,0.9616,0.4899,0.4,0.6375,0.4896,0.658,80,0.0714,0.2232,0.153
|
| 4 |
+
Qwen3-Embedding-0.6B,Qwen/Qwen3-Embedding-0.6B,Qwen/Qwen3-Embedding-0.6B,public,baseline,qwen3,dev,512,float16,0.5449,0.5327,0.1735,0.6297,0.8985,0.4902,0.4353,0.6353,0.4797,0.8552,85,0.1107,0.2519,0.1495
|
| 5 |
+
Qwen3-Embedding-0.6B,Qwen/Qwen3-Embedding-0.6B,Qwen/Qwen3-Embedding-0.6B,public,baseline,qwen3,test,512,float16,0.5576,0.5634,0.2784,0.6186,0.9051,0.4227,0.4875,0.6375,0.5297,0.8663,80,0.1458,0.3393,0.3135
|
| 6 |
+
bge-m3,BAAI/bge-m3,BAAI/bge-m3,public,baseline,bge-m3,dev,512,float16,0.5923,0.6183,0.2443,0.6617,0.9363,0.5011,0.5412,0.6824,0.5743,0.8859,85,0.1641,0.3435,0.2135
|
| 7 |
+
bge-m3,BAAI/bge-m3,BAAI/bge-m3,public,baseline,bge-m3,test,512,float16,0.6332,0.596,0.3778,0.7174,0.9578,0.5168,0.55,0.65,0.5581,0.9375,80,0.2262,0.4286,0.4113
|
| 8 |
+
multilingual-e5-base,intfloat/multilingual-e5-base,intfloat/multilingual-e5-base,public,baseline,e5,dev,512,float16,0.5737,0.5728,0.1827,0.6293,0.9381,0.5457,0.4588,0.6706,0.5452,0.7411,85,0.1031,0.2901,0.1504
|
| 9 |
+
multilingual-e5-base,intfloat/multilingual-e5-base,intfloat/multilingual-e5-base,public,baseline,e5,test,512,float16,0.5532,0.5626,0.2776,0.6139,0.854,0.458,0.4875,0.6375,0.5243,0.9077,80,0.1488,0.3512,0.3161
|
| 10 |
+
multilingual-e5-large,intfloat/multilingual-e5-large,intfloat/multilingual-e5-large,public,baseline,e5,dev,512,float16,0.5872,0.6028,0.2004,0.6524,0.9425,0.5379,0.4941,0.7294,0.5646,0.8348,85,0.126,0.2977,0.1709
|
| 11 |
+
multilingual-e5-large,intfloat/multilingual-e5-large,intfloat/multilingual-e5-large,public,baseline,e5,test,512,float16,0.5977,0.5886,0.3122,0.6706,0.9413,0.4758,0.525,0.6625,0.5565,0.8772,80,0.1756,0.378,0.3971
|
| 12 |
+
multilingual-e5-small,intfloat/multilingual-e5-small,intfloat/multilingual-e5-small,public,baseline,e5,dev,512,float16,0.5353,0.5467,0.1186,0.5698,0.9311,0.5101,0.4824,0.6235,0.5115,0.7609,85,0.084,0.1641,0.1047
|
| 13 |
+
multilingual-e5-small,intfloat/multilingual-e5-small,intfloat/multilingual-e5-small,public,baseline,e5,test,512,float16,0.5619,0.5381,0.2934,0.5664,0.9197,0.4918,0.4875,0.5875,0.4988,0.8914,80,0.1726,0.3661,0.2995
|
| 14 |
+
paraphrase-multilingual-mpnet-base-v2,sentence-transformers/paraphrase-multilingual-mpnet-base-v2,sentence-transformers/paraphrase-multilingual-mpnet-base-v2,public,baseline,mpnet,dev,512,float16,0.428,0.2822,0.1138,0.436,0.8869,0.421,0.1882,0.4,0.2702,0.3551,85,0.0573,0.187,0.0914
|
| 15 |
+
paraphrase-multilingual-mpnet-base-v2,sentence-transformers/paraphrase-multilingual-mpnet-base-v2,sentence-transformers/paraphrase-multilingual-mpnet-base-v2,public,baseline,mpnet,test,512,float16,0.4428,0.3399,0.0815,0.503,0.9018,0.3879,0.2375,0.4625,0.3353,0.3814,80,0,0.1637,0.0686
|
| 16 |
+
Round-1 model (e5-base fine-tune),r1-ft-e5-base,intfloat/multilingual-e5-base,round-1,incumbent; selected in round 1,e5,dev,256,float32,0.6851,0.6299,0.3288,0.8081,0.9432,0.7157,0.4941,0.7765,0.6024,0.7968,85,0.229,0.458,0.2894
|
| 17 |
+
Round-1 model (e5-base fine-tune),r1-ft-e5-base,intfloat/multilingual-e5-base,round-1,incumbent; selected in round 1,e5,test,256,float32,0.6923,0.6097,0.274,0.834,0.9827,0.7612,0.5375,0.675,0.5715,0.9539,80,0.1012,0.4315,0.2731
|
| 18 |
+
Round-1 e5-small fine-tune,r1-ft-e5-small,intfloat/multilingual-e5-small,round-1,incumbent,e5,dev,256,float32,0.67,0.6193,0.2778,0.7943,0.9382,0.7204,0.5294,0.7176,0.5912,0.7906,85,0.1679,0.416,0.2353
|
| 19 |
+
Round-1 e5-small fine-tune,r1-ft-e5-small,intfloat/multilingual-e5-small,round-1,incumbent,e5,test,256,float32,0.7197,0.6091,0.3664,0.8314,0.9736,0.8177,0.55,0.675,0.5708,0.9539,80,0.247,0.4196,0.4438
|
| 20 |
+
TF-IDF char 2-4-gram,tfidf-char2-4,,lexical,reference,,dev,,,0.6667,0.6049,0.4594,0.7655,0.9463,0.5573,0.5294,0.6824,0.5656,0.8442,85,0.3282,0.6069,0.4132
|
| 21 |
+
TF-IDF char 2-4-gram,tfidf-char2-4,,lexical,reference,,test,,,0.6864,0.6173,0.3756,0.7899,0.9597,0.6895,0.55,0.6875,0.5879,0.8827,80,0.1875,0.503,0.3579
|
| 22 |
+
Round-2 bge-m3 fine-tune,r2-bgem3,BAAI/bge-m3,round-2,candidate,bge-m3,dev,512,float16,0.7008,0.6459,0.4435,0.8246,0.9429,0.647,0.5529,0.7294,0.6064,0.8859,85,0.3397,0.5573,0.4077
|
| 23 |
+
"Round-2 e5-base fine-tune, no mined negatives",r2-e5b-plain,intfloat/multilingual-e5-base,round-2,candidate (ablation),e5,dev,512,float16,0.7066,0.5941,0.4408,0.8295,0.9453,0.7234,0.4824,0.7059,0.5722,0.7272,85,0.3359,0.5534,0.4053
|
| 24 |
+
Round-2 e5-base fine-tune,r2-e5b,intfloat/multilingual-e5-base,round-2,runner-up,e5,dev,512,float16,0.7079,0.6006,0.4464,0.8176,0.9411,0.7339,0.4941,0.7059,0.5744,0.7598,85,0.3473,0.5496,0.4137
|
| 25 |
+
Round-2 e5-base fine-tune,r2-e5b,intfloat/multilingual-e5-base,round-2,runner-up,e5,test,512,float16,0.6919,0.6027,0.2422,0.835,0.9818,0.7979,0.5375,0.65,0.5706,0.8914,80,0.1071,0.3542,0.251
|
| 26 |
+
Hindko Embeddings (this model),r2-e5l,intfloat/multilingual-e5-large,round-2,selected (released),e5,dev,512,float16,0.7117,0.6357,0.4257,0.8308,0.9406,0.7258,0.5294,0.7412,0.5963,0.875,85,0.2977,0.563,0.3826
|
| 27 |
+
Hindko Embeddings (this model),r2-e5l,intfloat/multilingual-e5-large,round-2,selected (released),e5,test,512,float16,0.7391,0.6372,0.346,0.8756,0.9801,0.8566,0.5625,0.7125,0.6072,0.9077,80,0.1548,0.4494,0.3608
|
| 28 |
+
Round-2 e5-small fine-tune,r2-e5s,intfloat/multilingual-e5-small,round-2,candidate,e5,dev,512,float16,0.7039,0.6191,0.4358,0.8094,0.948,0.707,0.5294,0.7176,0.5899,0.7968,85,0.3397,0.5458,0.4015
|
eval/selection.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"rule": "pool = round-2 dev results + incumbents ft-e5-base (size 2) and ft-e5-small (size 1) with their round-1 dev scores; best = max overall; near = overall >= best - 0.003; selected = smallest size rank in near (ties by higher score); runner-up = best-scoring other model",
|
| 3 |
+
"dev_scores": {
|
| 4 |
+
"ft-e5-base": 0.6851297501603847,
|
| 5 |
+
"ft-e5-small": 0.6700276166417629,
|
| 6 |
+
"r2-bgem3": 0.7007568407810918,
|
| 7 |
+
"r2-e5b": 0.7079351835925609,
|
| 8 |
+
"r2-e5b-plain": 0.7066095544829916,
|
| 9 |
+
"r2-e5l": 0.7117165057564516,
|
| 10 |
+
"r2-e5s": 0.7038754488016046
|
| 11 |
+
},
|
| 12 |
+
"near": [
|
| 13 |
+
"r2-e5l"
|
| 14 |
+
],
|
| 15 |
+
"selected": "r2-e5l",
|
| 16 |
+
"runner_up": "r2-e5b",
|
| 17 |
+
"tie": 0.003,
|
| 18 |
+
"written_utc": "2026-10-01T17:48:17Z",
|
| 19 |
+
"gate": {
|
| 20 |
+
"pass": true,
|
| 21 |
+
"decided_utc": "2026-10-01T15:38:50Z",
|
| 22 |
+
"BookTitleRetrieval": 0.446437329167755,
|
| 23 |
+
"overall": 0.7079351835925609,
|
| 24 |
+
"BookClustering": 0.7339101300956627
|
| 25 |
+
},
|
| 26 |
+
"pairs_sha256": {
|
| 27 |
+
"rows.jsonl": "9ddde8f6ef2750166e4d895b8aba55ba394ba954961169ab0aec0f5d4a541faa",
|
| 28 |
+
"texts.jsonl": "f0c31d84f79e7c3cee0b45e708ec1bb1929f9e2d99d7fbdec66ecb47a1024a28"
|
| 29 |
+
},
|
| 30 |
+
"size_rank": {
|
| 31 |
+
"r2-e5s": 1,
|
| 32 |
+
"ft-e5-small": 1,
|
| 33 |
+
"r2-e5b": 2,
|
| 34 |
+
"r2-e5b-plain": 2,
|
| 35 |
+
"ft-e5-base": 2,
|
| 36 |
+
"r2-e5l": 3,
|
| 37 |
+
"r2-bgem3": 4
|
| 38 |
+
},
|
| 39 |
+
"notes": "dev_scores of ft-e5-base and ft-e5-small are their round-1 dev results (max_seq_length 256, float32); all other pool members were evaluated at max_seq_length 512 in float16. Test was run once, after this selection, on the selected model and the runner-up. gate = the pre-registered recipe gate evaluated on r2-e5b dev (BookTitleRetrieval >= 0.36, overall >= 0.685, BookClustering >= 0.68); pass -> the large runs used mined hard negatives and same-book blocks."
|
| 40 |
+
}
|
eval/training.json
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"runs": {
|
| 3 |
+
"r2-bgem3": {
|
| 4 |
+
"base": "BAAI/bge-m3",
|
| 5 |
+
"lr": 1.5e-05,
|
| 6 |
+
"epochs": 2,
|
| 7 |
+
"batch": 256,
|
| 8 |
+
"mini": 32,
|
| 9 |
+
"max_seq_length": 512,
|
| 10 |
+
"negatives": "on",
|
| 11 |
+
"block": 32,
|
| 12 |
+
"steps": 322,
|
| 13 |
+
"train_seconds": 1608.7,
|
| 14 |
+
"peak_gb": 25.564,
|
| 15 |
+
"gpu": "NVIDIA A100-SXM4-80GB"
|
| 16 |
+
},
|
| 17 |
+
"r2-e5b-plain": {
|
| 18 |
+
"base": "intfloat/multilingual-e5-base",
|
| 19 |
+
"lr": 3e-05,
|
| 20 |
+
"epochs": 2,
|
| 21 |
+
"batch": 256,
|
| 22 |
+
"mini": 64,
|
| 23 |
+
"max_seq_length": 512,
|
| 24 |
+
"negatives": "off",
|
| 25 |
+
"block": 0,
|
| 26 |
+
"steps": 322,
|
| 27 |
+
"train_seconds": 369.8,
|
| 28 |
+
"peak_gb": 17.084,
|
| 29 |
+
"gpu": "NVIDIA A100-SXM4-80GB"
|
| 30 |
+
},
|
| 31 |
+
"r2-e5b": {
|
| 32 |
+
"base": "intfloat/multilingual-e5-base",
|
| 33 |
+
"lr": 3e-05,
|
| 34 |
+
"epochs": 2,
|
| 35 |
+
"batch": 256,
|
| 36 |
+
"mini": 64,
|
| 37 |
+
"max_seq_length": 512,
|
| 38 |
+
"negatives": "on",
|
| 39 |
+
"block": 32,
|
| 40 |
+
"steps": 322,
|
| 41 |
+
"train_seconds": 548.6,
|
| 42 |
+
"peak_gb": 17.091,
|
| 43 |
+
"gpu": "NVIDIA A100-SXM4-80GB"
|
| 44 |
+
},
|
| 45 |
+
"r2-e5l": {
|
| 46 |
+
"base": "intfloat/multilingual-e5-large",
|
| 47 |
+
"lr": 2e-05,
|
| 48 |
+
"epochs": 2,
|
| 49 |
+
"batch": 256,
|
| 50 |
+
"mini": 32,
|
| 51 |
+
"max_seq_length": 512,
|
| 52 |
+
"negatives": "on",
|
| 53 |
+
"block": 32,
|
| 54 |
+
"steps": 322,
|
| 55 |
+
"train_seconds": 1620.1,
|
| 56 |
+
"peak_gb": 25.447,
|
| 57 |
+
"gpu": "NVIDIA A100-SXM4-80GB"
|
| 58 |
+
},
|
| 59 |
+
"r2-e5s": {
|
| 60 |
+
"base": "intfloat/multilingual-e5-small",
|
| 61 |
+
"lr": 5e-05,
|
| 62 |
+
"epochs": 2,
|
| 63 |
+
"batch": 256,
|
| 64 |
+
"mini": 128,
|
| 65 |
+
"max_seq_length": 512,
|
| 66 |
+
"negatives": "on",
|
| 67 |
+
"block": 32,
|
| 68 |
+
"steps": 322,
|
| 69 |
+
"train_seconds": 309.6,
|
| 70 |
+
"peak_gb": 14.999,
|
| 71 |
+
"gpu": "NVIDIA A100-SXM4-80GB"
|
| 72 |
+
}
|
| 73 |
+
},
|
| 74 |
+
"train_rows": {
|
| 75 |
+
"title": 4391,
|
| 76 |
+
"verse_ict": 2949,
|
| 77 |
+
"prose_q": 6939,
|
| 78 |
+
"continuation": 12904,
|
| 79 |
+
"neighbour": 14350,
|
| 80 |
+
"total": 41533
|
| 81 |
+
},
|
| 82 |
+
"common": {
|
| 83 |
+
"epochs": 2,
|
| 84 |
+
"batch_size": 256,
|
| 85 |
+
"warmup": "10% of steps, linear decay",
|
| 86 |
+
"weight_decay": 0.01,
|
| 87 |
+
"loss": "CachedMultipleNegativesRankingLoss(scale=20.0, mini_batch_size=mini)",
|
| 88 |
+
"seed": 20261001,
|
| 89 |
+
"prefixes_e5": {
|
| 90 |
+
"title, verse_ict, prose_q, continuation": [
|
| 91 |
+
"query: ",
|
| 92 |
+
"passage: "
|
| 93 |
+
],
|
| 94 |
+
"neighbour": [
|
| 95 |
+
"query: ",
|
| 96 |
+
"query: "
|
| 97 |
+
]
|
| 98 |
+
},
|
| 99 |
+
"mixed_precision": "bf16 on GPUs with compute capability >= 8 (A100)",
|
| 100 |
+
"saved_dtype": "float16"
|
| 101 |
+
},
|
| 102 |
+
"released": {
|
| 103 |
+
"name": "r2-e5l",
|
| 104 |
+
"weights": "1068 MB fp16"
|
| 105 |
+
}
|
| 106 |
+
}
|
make_charts.py
ADDED
|
@@ -0,0 +1,402 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Benchmark images for Hindko Embeddings (model card), in the style of the Hindko Tokenizer charts.
|
| 2 |
+
|
| 3 |
+
Every score is read from eval/results.csv and eval/selection.json in this folder; nothing is typed in by hand
|
| 4 |
+
except the task sizes (HindkoEmbedBench v1.0 description) and the parameter counts of the public models (PARAMS).
|
| 5 |
+
Writes benchmarks/<nn>_<name>.png (3200 x 1800): HTML pages rendered by headless Chrome at 2x, with the Google
|
| 6 |
+
Fonts embedded so they always load.
|
| 7 |
+
|
| 8 |
+
python make_charts.py # all charts
|
| 9 |
+
python make_charts.py 00,03 # only these
|
| 10 |
+
python make_charts.py --keep-html
|
| 11 |
+
"""
|
| 12 |
+
import base64
|
| 13 |
+
import csv
|
| 14 |
+
import json
|
| 15 |
+
import os
|
| 16 |
+
import re
|
| 17 |
+
import shutil
|
| 18 |
+
import subprocess
|
| 19 |
+
import sys
|
| 20 |
+
import urllib.request
|
| 21 |
+
|
| 22 |
+
sys.dont_write_bytecode = True
|
| 23 |
+
HERE = os.path.dirname(os.path.abspath(__file__))
|
| 24 |
+
EVAL = os.path.join(HERE, 'eval')
|
| 25 |
+
OUT = os.path.join(HERE, 'benchmarks')
|
| 26 |
+
WORK = os.path.join(HERE, '.render') # HTML sources and the Chrome profile; removed afterwards
|
| 27 |
+
CHROME = (os.environ.get('CHROME') or shutil.which('chrome') or shutil.which('google-chrome') or shutil.which('chromium')
|
| 28 |
+
or os.path.join(os.environ.get('PROGRAMFILES', ''), 'Google', 'Chrome', 'Application', 'chrome.exe'))
|
| 29 |
+
UA = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0 Safari/537.36'}
|
| 30 |
+
W, H = 1600, 900
|
| 31 |
+
|
| 32 |
+
# ------------------------------------------------------------------------------------------------ data
|
| 33 |
+
R = {}
|
| 34 |
+
for r in csv.DictReader(open(os.path.join(EVAL, 'results.csv'), encoding='utf-8')):
|
| 35 |
+
R[(r['model_id'], r['split'])] = r
|
| 36 |
+
SEL = json.load(open(os.path.join(EVAL, 'selection.json'), encoding='utf-8'))
|
| 37 |
+
|
| 38 |
+
OURS = SEL['selected'] # r2-e5l
|
| 39 |
+
RUNNER = SEL['runner_up'] # r2-e5b
|
| 40 |
+
TFIDF = 'tfidf-char2-4'
|
| 41 |
+
R1 = 'r1-ft-e5-base' # round-1 model (selected in round 1)
|
| 42 |
+
R1S = 'r1-ft-e5-small'
|
| 43 |
+
BGE = 'BAAI/bge-m3'
|
| 44 |
+
E5L = 'intfloat/multilingual-e5-large'
|
| 45 |
+
POOL_ID = {'ft-e5-base': R1, 'ft-e5-small': R1S} # selection.json names -> results.csv model_id
|
| 46 |
+
TASKS = ['HeadlineRetrieval', 'BookTitleRetrieval', 'PassageContinuation', 'VerseProseClassification', 'BookClustering']
|
| 47 |
+
TASK_LABEL = {'overall': ('Overall', 'mean of 5'), 'HeadlineRetrieval': ('Headline', 'nDCG@10'),
|
| 48 |
+
'BookTitleRetrieval': ('Book title', 'nDCG@10'), 'PassageContinuation': ('Continuation', 'nDCG@10'),
|
| 49 |
+
'VerseProseClassification': ('Verse / prose', 'macro-F1'), 'BookClustering': ('Book clustering', 'V-measure')}
|
| 50 |
+
# HindkoEmbedBench v1.0 task sizes (benchmark description)
|
| 51 |
+
SIZES = {'dev': '85 headline, 262 book-title and 416 continuation queries; 297 verse/prose and 355 clustering items',
|
| 52 |
+
'test': '80 headline, 28 book-title and 360 continuation queries; 157 verse/prose and 176 clustering items'}
|
| 53 |
+
# parameters in millions: e5-small/-base and mpnet counted from their safetensors; e5-large, bge-m3, LaBSE and
|
| 54 |
+
# Qwen3-Embedding-0.6B as listed on their Hugging Face model pages. Fine-tuning does not change the count.
|
| 55 |
+
PARAMS = {'intfloat/multilingual-e5-small': 118, 'intfloat/multilingual-e5-base': 278, 'intfloat/multilingual-e5-large': 560,
|
| 56 |
+
'BAAI/bge-m3': 568, 'sentence-transformers/LaBSE': 471, 'Qwen/Qwen3-Embedding-0.6B': 596,
|
| 57 |
+
'sentence-transformers/paraphrase-multilingual-mpnet-base-v2': 278}
|
| 58 |
+
|
| 59 |
+
PUBLIC = [(m, s) for (m, s), r in R.items() if r['kind'] == 'public' and s == 'test']
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
def v(mid, split, col='overall'):
|
| 63 |
+
return float(R[(mid, split)][col])
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
def f3(x):
|
| 67 |
+
return '%.3f' % x
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
def f4(x):
|
| 71 |
+
return '%.4f' % x
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
def short(mid):
|
| 75 |
+
return mid.split('/')[-1]
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
# ------------------------------------------------------------------------------------------------ page
|
| 79 |
+
CSS = """
|
| 80 |
+
:root{--ink:#0F172A;--muted:#5B6576;--grid:#E4E8EE;--accent:#2F6FDB;--accent-ink:#1D4FA8;--bar:#C9D0DA;--soft:#EAF1FC}
|
| 81 |
+
*{box-sizing:border-box}
|
| 82 |
+
html,body{margin:0;width:%(W)dpx;height:%(H)dpx;overflow:hidden;background:#FFFFFF;color:var(--ink);font-family:'IBM Plex Sans',sans-serif}
|
| 83 |
+
.page{position:absolute;inset:0;padding:56px 80px 0}
|
| 84 |
+
.eyebrow{font-size:17px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--accent)}
|
| 85 |
+
h1{font-family:'Source Serif 4',serif;font-weight:600;font-size:54px;line-height:1.08;letter-spacing:-.015em;margin:12px 0 10px}
|
| 86 |
+
.sub{font-size:23px;line-height:1.4;color:var(--muted);max-width:1400px;margin:0}
|
| 87 |
+
.foot{position:absolute;left:80px;right:80px;bottom:34px;display:flex;justify-content:space-between;gap:40px;font-size:16px;color:var(--muted);border-top:1px solid var(--grid);padding-top:14px}
|
| 88 |
+
.foot b{color:var(--ink);font-weight:600}
|
| 89 |
+
.bars{margin-top:30px}
|
| 90 |
+
.row{display:grid;grid-template-columns:380px 1fr 120px;align-items:center;column-gap:22px;height:%(rowh)dpx}
|
| 91 |
+
.lab{font-size:21px;line-height:1.15;text-align:right}
|
| 92 |
+
.lab small{display:block;font-size:15px;color:var(--muted)}
|
| 93 |
+
.trk{position:relative;height:%(barh)dpx}
|
| 94 |
+
.fill{position:absolute;left:0;top:0;bottom:0;background:var(--bar);border-radius:0 4px 4px 0}
|
| 95 |
+
.val{font-size:21px;font-variant-numeric:tabular-nums;color:var(--ink)}
|
| 96 |
+
.row.me .lab{font-weight:700}.row.me .fill{background:var(--accent)}.row.me .val{font-weight:700;color:var(--accent-ink)}
|
| 97 |
+
.row.ref .fill{background:#8E9AAB}
|
| 98 |
+
.gl{position:absolute;top:-8px;bottom:-8px;border-left:1px dashed var(--grid)}
|
| 99 |
+
table{border-collapse:collapse;width:100%%;margin-top:30px;font-variant-numeric:tabular-nums}
|
| 100 |
+
th{font-size:15px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);text-align:right;padding:0 18px 12px;border-bottom:2px solid var(--ink);vertical-align:bottom}
|
| 101 |
+
th small{display:block;font-size:13px;letter-spacing:.02em;text-transform:none;font-weight:400}
|
| 102 |
+
th:first-child,td:first-child{text-align:left;padding-left:0}
|
| 103 |
+
td{font-size:22px;text-align:right;padding:13px 18px;border-bottom:1px solid var(--grid)}
|
| 104 |
+
td small{font-size:15px;color:var(--muted);margin-left:8px;font-weight:400}
|
| 105 |
+
td .best{border-bottom:3px solid currentColor;padding-bottom:1px}
|
| 106 |
+
tr.me td{font-weight:700;color:var(--accent-ink);background:var(--soft)}
|
| 107 |
+
tr.me td:first-child{padding-left:14px;border-radius:6px 0 0 6px}
|
| 108 |
+
.legend{display:flex;gap:34px;font-size:19px;margin-top:26px}
|
| 109 |
+
.legend span{display:inline-flex;align-items:center;gap:10px}
|
| 110 |
+
.legend i{display:inline-block;width:22px;height:16px;border-radius:3px}
|
| 111 |
+
.note{font-size:19px;line-height:1.45;color:var(--muted);max-width:1440px;margin-top:18px}
|
| 112 |
+
"""
|
| 113 |
+
|
| 114 |
+
HEAD = ('<!doctype html><html><head><meta charset="utf-8">'
|
| 115 |
+
'<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;600;700'
|
| 116 |
+
'&family=Source+Serif+4:opsz,wght@8..60,600&display=block">'
|
| 117 |
+
'<style>%s</style></head><body><div class="page">')
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
def page(title, sub, body, foot_left, rowh=52, barh=30):
|
| 121 |
+
return (HEAD % (CSS % dict(W=W, H=H, rowh=rowh, barh=barh)) +
|
| 122 |
+
'<div class="eyebrow">Hindko Embeddings · Benchmarks</div><h1>%s</h1><p class="sub">%s</p>%s'
|
| 123 |
+
'<div class="foot"><span>%s</span><span style="white-space:nowrap">huggingface.co/junaid008/hindko-embeddings</span></div></div></body></html>'
|
| 124 |
+
% (title, sub, body, foot_left))
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
def foot(split, extra=''):
|
| 128 |
+
name = 'Test split, scored once after selection on dev' if split == 'test' else 'Dev (validation) split'
|
| 129 |
+
return '<b>HindkoEmbedBench v1.0 · %s</b>%s' % (name, extra)
|
| 130 |
+
|
| 131 |
+
|
| 132 |
+
def bars(items, vmax, grid=()):
|
| 133 |
+
"""items: (label, sublabel, value, value_html, cls) with cls '', 'me' or 'ref'."""
|
| 134 |
+
out = ['<div class="bars">']
|
| 135 |
+
for lab, sublab, val, vh, cls in items:
|
| 136 |
+
gl = ''.join('<span class="gl" style="left:%.3f%%"></span>' % (100 * g / vmax) for g in grid)
|
| 137 |
+
out.append('<div class="row %s"><div class="lab">%s%s</div><div class="trk">%s<div class="fill" style="width:%.3f%%"></div></div>'
|
| 138 |
+
'<div class="val">%s</div></div>' % (cls, lab, '<small>%s</small>' % sublab if sublab else '', gl, 100 * val / vmax, vh))
|
| 139 |
+
out.append('</div>')
|
| 140 |
+
return ''.join(out)
|
| 141 |
+
|
| 142 |
+
|
| 143 |
+
def legend(series):
|
| 144 |
+
return '<div class="legend">%s</div>' % ''.join('<span><i style="background:%s"></i>%s</span>' % (c, n) for n, c in series)
|
| 145 |
+
|
| 146 |
+
|
| 147 |
+
def grouped(groups, series, vmax=1.0, width=1440, height=470, ticks=(0.2, 0.4, 0.6, 0.8, 1.0), x0=60, label_fmt=f3,
|
| 148 |
+
bar_w=None, gap=10, lab_size=16, below=None):
|
| 149 |
+
"""Vertical grouped columns. groups: [(title, subtitle)]; series: [(name, color, [values], bold)]."""
|
| 150 |
+
y0, y1 = 22, height - 70
|
| 151 |
+
plot_w = width - x0 - 10
|
| 152 |
+
gw = plot_w / len(groups)
|
| 153 |
+
n = len(series)
|
| 154 |
+
bw = bar_w or min(64, (gw - 50 - gap * (n - 1)) / n)
|
| 155 |
+
svg = ['<svg viewBox="0 0 %d %d" width="%d" height="%d" style="display:block;margin-top:14px;overflow:visible">' % (width, height, width, height)]
|
| 156 |
+
Y = lambda val: y1 - (y1 - y0) * val / vmax
|
| 157 |
+
for t in ticks:
|
| 158 |
+
svg.append('<line x1="%d" x2="%d" y1="%.1f" y2="%.1f" stroke="#E4E8EE"/><text x="%d" y="%.1f" font-size="15" fill="#5B6576" text-anchor="end">%.1f</text>'
|
| 159 |
+
% (x0, width - 10, Y(t), Y(t), x0 - 10, Y(t) + 5, t))
|
| 160 |
+
svg.append('<line x1="%d" x2="%d" y1="%d" y2="%d" stroke="#0F172A" stroke-width="1.5"/>' % (x0, width - 10, y1, y1))
|
| 161 |
+
for gi, (gt, gs) in enumerate(groups):
|
| 162 |
+
gx = x0 + gi * gw
|
| 163 |
+
total = n * bw + (n - 1) * gap
|
| 164 |
+
bx0 = gx + (gw - total) / 2
|
| 165 |
+
for si, (name, col, vals, bold) in enumerate(series):
|
| 166 |
+
val = vals[gi]
|
| 167 |
+
if val is None:
|
| 168 |
+
continue
|
| 169 |
+
x = bx0 + si * (bw + gap)
|
| 170 |
+
svg.append('<rect x="%.1f" y="%.1f" width="%.1f" height="%.1f" fill="%s" rx="3"/>' % (x, Y(val), bw, y1 - Y(val), col))
|
| 171 |
+
svg.append('<text x="%.1f" y="%.1f" font-size="%d" font-weight="%d" fill="%s" text-anchor="middle">%s</text>'
|
| 172 |
+
% (x + bw / 2, Y(val) - 8, lab_size, 700 if bold else 400, '#1D4FA8' if bold else '#0F172A', label_fmt(val)))
|
| 173 |
+
svg.append('<text x="%.1f" y="%d" font-size="19" font-weight="600" fill="#0F172A" text-anchor="middle">%s</text>' % (gx + gw / 2, y1 + 28, gt))
|
| 174 |
+
svg.append('<text x="%.1f" y="%d" font-size="15" fill="#5B6576" text-anchor="middle">%s</text>' % (gx + gw / 2, y1 + 50, gs))
|
| 175 |
+
if below:
|
| 176 |
+
svg.append(below(gi, gx, gw, y1))
|
| 177 |
+
svg.append('</svg>')
|
| 178 |
+
return ''.join(svg)
|
| 179 |
+
|
| 180 |
+
|
| 181 |
+
# ------------------------------------------------------------------------------------------------ 00 scorecard
|
| 182 |
+
def c00():
|
| 183 |
+
rows = [(OURS, 'Hindko Embeddings', 'this model · 512 tokens'),
|
| 184 |
+
(TFIDF, 'TF-IDF char 2-4-gram', 'lexical reference'),
|
| 185 |
+
(RUNNER, 'Round-2 e5-base fine-tune', 'runner-up on dev · 512 tokens'),
|
| 186 |
+
(R1, 'Round-1 model', 'our e5-base fine-tune · 256 tokens'),
|
| 187 |
+
(R1S, 'Round-1 e5-small fine-tune', '256 tokens'),
|
| 188 |
+
(BGE, 'bge-m3', 'best public model · 512 tokens'),
|
| 189 |
+
(E5L, 'multilingual-e5-large', 'base model, untuned · 512 tokens')]
|
| 190 |
+
rows.sort(key=lambda r: -v(r[0], 'test')) # ranked by overall test score, like the README table
|
| 191 |
+
cols = ['overall'] + TASKS
|
| 192 |
+
best = {c: max(v(m, 'test', c) for m, _, _ in rows) for c in cols}
|
| 193 |
+
head = ''.join('<th>%s<small>%s</small></th>' % TASK_LABEL[c] for c in cols)
|
| 194 |
+
trs = []
|
| 195 |
+
for m, name, sub in rows:
|
| 196 |
+
tds = ''.join('<td>%s</td>' % (('<span class="best">%s</span>' if v(m, 'test', c) == best[c] else '%s') % f3(v(m, 'test', c))) for c in cols)
|
| 197 |
+
trs.append('<tr%s><td>%s<small>%s</small></td>%s</tr>' % (' class="me"' if m == OURS else '', name, sub, tds))
|
| 198 |
+
body = '<table><tr><th>Model</th>%s</tr>%s</table>' % (head, ''.join(trs))
|
| 199 |
+
d_tf = v(OURS, 'test') - v(TFIDF, 'test')
|
| 200 |
+
d_bge = v(OURS, 'test') - v(BGE, 'test')
|
| 201 |
+
body += ('<p class="note">Overall: <b style="color:#0F172A">+%.3f</b> over TF-IDF and <b style="color:#0F172A">+%.3f</b> over bge-m3. '
|
| 202 |
+
'Ahead of TF-IDF on four of the five tasks; behind it, and behind bge-m3, on book-title retrieval (28 test queries).</p>' % (d_tf, d_bge))
|
| 203 |
+
return page('Hindko Embeddings on the held-out test set',
|
| 204 |
+
'Five automatic Hindko tasks; higher is better. The best value in each column is underlined.', body,
|
| 205 |
+
foot('test', ' · neural models at max_seq_length 512 unless noted'))
|
| 206 |
+
|
| 207 |
+
|
| 208 |
+
# ------------------------------------------------------------------------------------------------ 01 overall, all models
|
| 209 |
+
def c01():
|
| 210 |
+
items = [('Hindko Embeddings', 'this model · e5-large fine-tune', v(OURS, 'test'), f4(v(OURS, 'test')), 'me'),
|
| 211 |
+
('Round-1 e5-small fine-tune', 'ours, round 1 · 256 tokens', v(R1S, 'test'), f4(v(R1S, 'test')), ''),
|
| 212 |
+
('Round-1 model', 'ours, round 1 · e5-base · 256 tokens', v(R1, 'test'), f4(v(R1, 'test')), ''),
|
| 213 |
+
('Round-2 e5-base fine-tune', 'ours, runner-up on dev', v(RUNNER, 'test'), f4(v(RUNNER, 'test')), ''),
|
| 214 |
+
('TF-IDF char 2-4-gram', 'lexical reference', v(TFIDF, 'test'), f4(v(TFIDF, 'test')), 'ref')]
|
| 215 |
+
for m, s in PUBLIC:
|
| 216 |
+
items.append((short(m).replace('paraphrase-', ''), 'public, untuned', v(m, 'test'), f4(v(m, 'test')), ''))
|
| 217 |
+
items.sort(key=lambda x: -x[2])
|
| 218 |
+
return page('Overall score on the test set',
|
| 219 |
+
'Mean of the five task scores for every model tested. Public models run untuned at 512 tokens; higher is better.',
|
| 220 |
+
bars(items, 0.8, grid=(0.2, 0.4, 0.6)) +
|
| 221 |
+
'<div style="display:grid;grid-template-columns:380px 1fr 120px;column-gap:22px;margin-top:2px"><span></span>'
|
| 222 |
+
'<div style="position:relative;height:20px;font-size:15px;color:#5B6576">%s</div><span></span></div>'
|
| 223 |
+
% ''.join('<span style="position:absolute;left:%.3f%%;transform:translateX(-50%%)">%.1f</span>' % (100 * t / 0.8, t) for t in (0.0, 0.2, 0.4, 0.6, 0.8)),
|
| 224 |
+
foot('test', ' · max_seq_length 512, except the round-1 models (256) and TF-IDF'), rowh=47, barh=26)
|
| 225 |
+
|
| 226 |
+
|
| 227 |
+
# ------------------------------------------------------------------------------------------------ 02 per task, test
|
| 228 |
+
def c02():
|
| 229 |
+
cols = ['overall'] + TASKS
|
| 230 |
+
series = [('Hindko Embeddings (this model)', '#2F6FDB', [v(OURS, 'test', c) for c in cols], True),
|
| 231 |
+
('TF-IDF char 2-4-gram', '#8E9AAB', [v(TFIDF, 'test', c) for c in cols], False),
|
| 232 |
+
('bge-m3, best public model', '#C9D0DA', [v(BGE, 'test', c) for c in cols], False)]
|
| 233 |
+
body = legend([(n, c) for n, c, _, _ in series]) + grouped([TASK_LABEL[c] for c in cols], series, height=500)
|
| 234 |
+
return page('Per-task scores on the test set',
|
| 235 |
+
'Ahead of TF-IDF on four of five tasks. On book-title retrieval (only 28 test queries) TF-IDF and bge-m3 score higher.',
|
| 236 |
+
body, foot('test', ' · neural models at max_seq_length 512'))
|
| 237 |
+
|
| 238 |
+
|
| 239 |
+
# ------------------------------------------------------------------------------------------------ 03 dev candidates
|
| 240 |
+
def c03():
|
| 241 |
+
pool = sorted(SEL['dev_scores'].items(), key=lambda kv: -kv[1])
|
| 242 |
+
best = pool[0][1]
|
| 243 |
+
lo, hi = 0.660, 0.720
|
| 244 |
+
X = lambda val: 100 * (val - lo) / (hi - lo)
|
| 245 |
+
sub = {'r2-e5l': 'e5-large · 560M · 512 tokens', 'r2-e5b': 'e5-base · 278M · 512 tokens',
|
| 246 |
+
'r2-e5b-plain': 'e5-base, no mined negatives or book blocks', 'r2-e5s': 'e5-small · 118M · 512 tokens',
|
| 247 |
+
'r2-bgem3': 'bge-m3 · 568M · 512 tokens', 'ft-e5-base': 'round-1 model · e5-base · 256 tokens',
|
| 248 |
+
'ft-e5-small': 'round-1 · e5-small · 256 tokens'}
|
| 249 |
+
tag = {SEL['selected']: 'selected', SEL['runner_up']: 'runner-up', 'ft-e5-base': 'incumbent', 'ft-e5-small': 'incumbent'}
|
| 250 |
+
rows = []
|
| 251 |
+
for name, val in pool:
|
| 252 |
+
me = name == SEL['selected']
|
| 253 |
+
dot = ('<div style="position:absolute;top:50%%;left:0;width:%.3f%%;height:2px;margin-top:-1px;background:%s"></div>'
|
| 254 |
+
'<div style="position:absolute;top:50%%;left:%.3f%%;width:18px;height:18px;margin:-9px 0 0 -9px;border-radius:50%%;background:%s"></div>'
|
| 255 |
+
% (X(val), '#9DB9EA' if me else '#D3D9E1', X(val), '#2F6FDB' if me else '#8E9AAB'))
|
| 256 |
+
rows.append('<div class="row%s" style="grid-template-columns:330px 1fr 230px;height:64px"><div class="lab">%s<small>%s</small></div>'
|
| 257 |
+
'<div class="trk" style="height:30px">%s</div><div class="val">%s<small style="font-size:15px;color:#5B6576;margin-left:10px;font-weight:400">%s</small></div></div>'
|
| 258 |
+
% (' me' if me else '', name, sub[name], dot, f4(val), tag.get(name, '')))
|
| 259 |
+
left = 'calc(330px + 22px + (100%% - 330px - 230px - 44px)*%.5f)'
|
| 260 |
+
band = ('<div style="position:absolute;top:0;bottom:0;left:%s;width:calc((100%% - 330px - 230px - 44px)*%.5f);background:#EAF1FC;border-left:1px solid #9DB9EA;border-right:1px solid #9DB9EA"></div>'
|
| 261 |
+
% (left % (X(best - SEL['tie']) / 100), (X(best) - X(best - SEL['tie'])) / 100))
|
| 262 |
+
tf = v(TFIDF, 'dev')
|
| 263 |
+
ref = ('<div style="position:absolute;top:0;bottom:0;left:%s;border-left:2px dashed #8E9AAB"></div>' % (left % (X(tf) / 100)))
|
| 264 |
+
ticks = ''.join('<span style="position:absolute;left:%s;transform:translateX(-50%%);font-size:15px;color:#5B6576">%.2f</span>' % (left % (X(t) / 100), t)
|
| 265 |
+
for t in (0.66, 0.67, 0.68, 0.69, 0.70, 0.71, 0.72))
|
| 266 |
+
body = ('<div style="position:relative;margin-top:26px">%s%s%s</div><div style="position:relative;height:22px;margin-top:4px">%s</div>'
|
| 267 |
+
'<p class="note" style="margin-top:14px">Shaded: the pre-registered tie band (within %.3f of the best). Only the best model falls in it, so it was selected; '
|
| 268 |
+
'the runner-up is %.4f below. Dashed line: TF-IDF on dev, %s. Axis starts at 0.66.</p>'
|
| 269 |
+
% (band, ref, ''.join(rows), ticks, SEL['tie'], best - SEL['dev_scores'][SEL['runner_up']], f4(tf)))
|
| 270 |
+
return page('Selected on dev by a fixed rule',
|
| 271 |
+
'Overall dev score of every model in the selection pool. Rule: highest dev score; within %.3f of it, the smaller model wins.' % SEL['tie'],
|
| 272 |
+
body, foot('dev', ' · round-2 models at 512 tokens in float16; incumbents at their round-1 setting'))
|
| 273 |
+
|
| 274 |
+
|
| 275 |
+
# ------------------------------------------------------------------------------------------------ 04 round 1 vs round 2
|
| 276 |
+
def c04():
|
| 277 |
+
cols = ['overall'] + TASKS
|
| 278 |
+
a = [v(R1, 'test', c) for c in cols]
|
| 279 |
+
b = [v(OURS, 'test', c) for c in cols]
|
| 280 |
+
series = [('Round-1 model (e5-base fine-tune, 256 tokens)', '#9DB9EA', a, False),
|
| 281 |
+
('Hindko Embeddings, round 2 (e5-large fine-tune, 512 tokens)', '#2F6FDB', b, True)]
|
| 282 |
+
|
| 283 |
+
def below(gi, gx, gw, y1):
|
| 284 |
+
d = float(f3(b[gi])) - float(f3(a[gi])) # from the rounded values printed on the bars
|
| 285 |
+
return ('<text x="%.1f" y="%d" font-size="17" font-weight="700" fill="%s" text-anchor="middle">%s</text>'
|
| 286 |
+
% (gx + gw / 2, y1 + 76, '#1D4FA8' if d >= 0 else '#B4442C', ('%+.3f' % d).replace('-', '−')))
|
| 287 |
+
body = legend([(n, c) for n, c, _, _ in series]) + grouped([TASK_LABEL[c] for c in cols], series, height=500, below=below)
|
| 288 |
+
return page('Round 2 vs round 1',
|
| 289 |
+
'Test scores, with the change below each group. Round 2 changed the base (e5-base to e5-large), the data (new short-query pairs, mined hard negatives, same-book batches) and the length (256 to 512 tokens).',
|
| 290 |
+
body, foot('test'))
|
| 291 |
+
|
| 292 |
+
|
| 293 |
+
# ------------------------------------------------------------------------------------------------ 05 size vs score
|
| 294 |
+
def c05():
|
| 295 |
+
width, height = 1440, 520
|
| 296 |
+
x0, x1, y0, y1 = 80, 1280, 20, height - 60
|
| 297 |
+
xmax, ylo, yhi = 650, 0.40, 0.75
|
| 298 |
+
X = lambda p: x0 + (x1 - x0) * p / xmax
|
| 299 |
+
Y = lambda s: y1 - (y1 - y0) * (s - ylo) / (yhi - ylo)
|
| 300 |
+
svg = ['<svg viewBox="0 0 %d %d" width="%d" height="%d" style="display:block;margin-top:26px;overflow:visible">' % (width, height, width, height)]
|
| 301 |
+
for t in (0.40, 0.45, 0.50, 0.55, 0.60, 0.65, 0.70, 0.75):
|
| 302 |
+
svg.append('<line x1="%d" x2="%d" y1="%.1f" y2="%.1f" stroke="#E4E8EE"/><text x="%d" y="%.1f" font-size="15" fill="#5B6576" text-anchor="end">%.2f</text>' % (x0, x1, Y(t), Y(t), x0 - 10, Y(t) + 5, t))
|
| 303 |
+
for p in (0, 100, 200, 300, 400, 500, 600):
|
| 304 |
+
svg.append('<text x="%.1f" y="%d" font-size="15" fill="#5B6576" text-anchor="middle">%d</text>' % (X(p), y1 + 24, p))
|
| 305 |
+
svg.append('<text x="%.1f" y="%d" font-size="16" fill="#5B6576" text-anchor="middle">parameters (millions)</text>' % ((x0 + x1) / 2, y1 + 50))
|
| 306 |
+
svg.append('<text x="18" y="%d" font-size="16" fill="#5B6576" transform="rotate(-90 18 %d)" text-anchor="middle">dev overall score</text>' % ((y0 + y1) // 2, (y0 + y1) // 2))
|
| 307 |
+
tf = v(TFIDF, 'dev')
|
| 308 |
+
svg.append('<line x1="%d" x2="%d" y1="%.1f" y2="%.1f" stroke="#8E9AAB" stroke-width="2" stroke-dasharray="7 6"/>' % (x0, x1, Y(tf), Y(tf)))
|
| 309 |
+
svg.append('<text x="%d" y="%.1f" font-size="16" fill="#5B6576" text-anchor="start">TF-IDF %s</text>' % (x0 + 8, Y(tf) - 8, f4(tf)))
|
| 310 |
+
e5 = ['intfloat/multilingual-e5-small', 'intfloat/multilingual-e5-base', 'intfloat/multilingual-e5-large']
|
| 311 |
+
ft = {'intfloat/multilingual-e5-small': 'r2-e5s', 'intfloat/multilingual-e5-base': 'r2-e5b', 'intfloat/multilingual-e5-large': OURS, BGE: 'r2-bgem3'}
|
| 312 |
+
for ids, col, w in (([ft[m] for m in e5], '#9DB9EA', 3), (e5, '#C9D0DA', 3)):
|
| 313 |
+
pts = ' '.join('%.1f,%.1f' % (X(PARAMS[m if m in PARAMS else [k for k, x in ft.items() if x == m][0]]), Y(v(m, 'dev'))) for m in ids)
|
| 314 |
+
svg.append('<polyline points="%s" fill="none" stroke="%s" stroke-width="%d"/>' % (pts, col, w))
|
| 315 |
+
for base, run in ft.items(): # fine-tuning gain per base: dotted vertical
|
| 316 |
+
svg.append('<line x1="%.1f" x2="%.1f" y1="%.1f" y2="%.1f" stroke="#C9D0DA" stroke-width="1.5" stroke-dasharray="3 4"/>'
|
| 317 |
+
% (X(PARAMS[base]), X(PARAMS[base]), Y(v(base, 'dev')), Y(v(run, 'dev'))))
|
| 318 |
+
# (id, label, dx, dy, anchor, kind)
|
| 319 |
+
pts = [(OURS, 'e5-large fine-tune (this model)', -14, -14, 'end', 'me'), ('r2-bgem3', 'bge-m3 fine-tune', 14, 26, 'start', 'ft'),
|
| 320 |
+
('r2-e5b', 'e5-base fine-tune', 0, -16, 'middle', 'ft'), ('r2-e5s', 'e5-small fine-tune', 0, -16, 'middle', 'ft'),
|
| 321 |
+
(E5L, 'e5-large', -14, -12, 'end', 'pub'), (BGE, 'bge-m3', 14, -10, 'start', 'pub'),
|
| 322 |
+
('intfloat/multilingual-e5-base', 'e5-base', 14, -10, 'start', 'pub'), ('intfloat/multilingual-e5-small', 'e5-small', 0, 28, 'middle', 'pub'),
|
| 323 |
+
('sentence-transformers/LaBSE', 'LaBSE', -14, 6, 'end', 'pub'), ('Qwen/Qwen3-Embedding-0.6B', 'Qwen3-Embedding-0.6B', 14, 6, 'start', 'pub'),
|
| 324 |
+
('sentence-transformers/paraphrase-multilingual-mpnet-base-v2', 'mpnet-base-v2', 14, 6, 'start', 'pub')]
|
| 325 |
+
inv = {r: b for b, r in ft.items()}
|
| 326 |
+
for mid, lab, dx, dy, anc, kind in pts:
|
| 327 |
+
p = PARAMS[mid] if mid in PARAMS else PARAMS[inv[mid]]
|
| 328 |
+
s = v(mid, 'dev')
|
| 329 |
+
col = {'me': '#2F6FDB', 'ft': '#6F95DE', 'pub': '#8E9AAB'}[kind]
|
| 330 |
+
r = 11 if kind == 'me' else 8
|
| 331 |
+
svg.append('<circle cx="%.1f" cy="%.1f" r="%d" fill="%s" stroke="#FFFFFF" stroke-width="2"/>' % (X(p), Y(s), r, col))
|
| 332 |
+
svg.append('<text x="%.1f" y="%.1f" font-size="%d" font-weight="%d" fill="%s" text-anchor="%s" stroke="#FFFFFF" stroke-width="5" paint-order="stroke">%s '
|
| 333 |
+
'<tspan font-weight="400" fill="#5B6576">%s</tspan></text>'
|
| 334 |
+
% (X(p) + dx, Y(s) + dy, 18 if kind == 'me' else 16, 700 if kind == 'me' else 600, '#1D4FA8' if kind == 'me' else '#0F172A', anc, lab, f4(s)))
|
| 335 |
+
svg.append('</svg>')
|
| 336 |
+
body = (legend([('fine-tuned on Hindko (round 2)', '#6F95DE'), ('public model, untuned', '#8E9AAB'), ('TF-IDF reference', '#8E9AAB')]).replace(
|
| 337 |
+
'<i style="background:#8E9AAB"></i>TF-IDF', '<i style="background:none;border-top:2px dashed #8E9AAB;height:0;width:28px"></i>TF-IDF') + ''.join(svg))
|
| 338 |
+
return page('Fine-tuning matters more than size',
|
| 339 |
+
'Dev score against model size. Every fine-tuned model scores above every untuned one; among the fine-tuned e5 models the larger ones score slightly higher.',
|
| 340 |
+
body, foot('dev', ' · neural models at max_seq_length 512 in float16; TF-IDF is lexical'))
|
| 341 |
+
|
| 342 |
+
|
| 343 |
+
# ------------------------------------------------------------------------------------------------ 06 book-title detail
|
| 344 |
+
def c06():
|
| 345 |
+
mets = [('BT_R1', 'Recall@1'), ('BT_R10', 'Recall@10'), ('BT_MRR', 'MRR@10'), ('BookTitleRetrieval', 'nDCG@10')]
|
| 346 |
+
panels = []
|
| 347 |
+
for split, title in (('dev', 'Dev: 262 queries'), ('test', 'Test: 28 queries from 5 books')):
|
| 348 |
+
series = [('this model', '#2F6FDB', [v(OURS, split, c) for c, _ in mets], True),
|
| 349 |
+
('TF-IDF', '#8E9AAB', [v(TFIDF, split, c) for c, _ in mets], False),
|
| 350 |
+
('bge-m3', '#C9D0DA', [v(BGE, split, c) for c, _ in mets], False)]
|
| 351 |
+
svg = grouped([(lab, '') for _, lab in mets], series, vmax=0.8, width=700, height=430, ticks=(0.2, 0.4, 0.6, 0.8), x0=50,
|
| 352 |
+
bar_w=44, gap=6, lab_size=15)
|
| 353 |
+
panels.append('<div><div style="font-size:22px;font-weight:600;margin-top:6px">%s</div>%s</div>' % (title, svg))
|
| 354 |
+
body = (legend([('Hindko Embeddings (this model)', '#2F6FDB'), ('TF-IDF char 2-4-gram', '#8E9AAB'), ('bge-m3 (untuned, 512 tokens)', '#C9D0DA')]) +
|
| 355 |
+
'<div style="display:grid;grid-template-columns:1fr 1fr;gap:40px">%s</div>' % ''.join(panels) +
|
| 356 |
+
'<p class="note" style="margin-top:0">The test set has only 28 queries (57 relevant passages), so its numbers are noisy; the dev gap to TF-IDF points the same way.</p>')
|
| 357 |
+
return page('Weak spot: finding a passage from its book title',
|
| 358 |
+
'BookTitleRetrieval: a table-of-contents title (often the first line of a poem) must retrieve its passage. TF-IDF beats this model on nDCG@10 on both dev and test.',
|
| 359 |
+
body, foot('test', '; dev panel on the dev split · neural models at max_seq_length 512'))
|
| 360 |
+
|
| 361 |
+
|
| 362 |
+
CHARTS = [('00_scorecard', c00), ('01_test_overall_all_models', c01), ('02_test_per_task', c02), ('03_dev_candidates', c03),
|
| 363 |
+
('04_round1_vs_round2', c04), ('05_size_vs_score', c05), ('06_booktitle_detail', c06)]
|
| 364 |
+
|
| 365 |
+
|
| 366 |
+
def embed_fonts(html):
|
| 367 |
+
for m in re.finditer(r'<link[^>]+href="(https://fonts.googleapis.com/css2?[^"]+)"[^>]*>', html):
|
| 368 |
+
url = m.group(1).replace('&', '&')
|
| 369 |
+
css = urllib.request.urlopen(urllib.request.Request(url, headers=UA), timeout=30).read().decode()
|
| 370 |
+
for u in sorted(set(re.findall(r'url\((https://fonts.gstatic.com/[^)]+)\)', css))):
|
| 371 |
+
data = urllib.request.urlopen(urllib.request.Request(u, headers=UA), timeout=60).read()
|
| 372 |
+
css = css.replace(u, 'data:font/woff2;base64,' + base64.b64encode(data).decode())
|
| 373 |
+
html = html.replace(m.group(0), '<style>' + css + '</style>')
|
| 374 |
+
return html
|
| 375 |
+
|
| 376 |
+
|
| 377 |
+
def main():
|
| 378 |
+
args = [a for a in sys.argv[1:] if not a.startswith('--')]
|
| 379 |
+
keep = '--keep-html' in sys.argv
|
| 380 |
+
only = args[0].split(',') if args else None
|
| 381 |
+
os.makedirs(OUT, exist_ok=True)
|
| 382 |
+
os.makedirs(WORK, exist_ok=True)
|
| 383 |
+
env = dict(os.environ, TEMP=WORK, TMP=WORK)
|
| 384 |
+
try:
|
| 385 |
+
for name, fn in CHARTS:
|
| 386 |
+
if only and name[:2] not in only:
|
| 387 |
+
continue
|
| 388 |
+
html = os.path.join(WORK, name + '.html')
|
| 389 |
+
open(html, 'w', encoding='utf-8', newline='\n').write(embed_fonts(fn()))
|
| 390 |
+
png = os.path.join(OUT, name + '.png')
|
| 391 |
+
subprocess.run([CHROME, '--headless=new', '--disable-gpu', '--hide-scrollbars', '--force-device-scale-factor=2',
|
| 392 |
+
'--user-data-dir=' + os.path.join(WORK, 'chrome'), '--no-first-run', '--disable-crash-reporter',
|
| 393 |
+
'--window-size=%d,%d' % (W, H), '--virtual-time-budget=20000', '--screenshot=' + png,
|
| 394 |
+
'file:///' + html.replace('\\', '/')], check=True, capture_output=True, timeout=300, env=env)
|
| 395 |
+
print(name)
|
| 396 |
+
finally:
|
| 397 |
+
if not keep:
|
| 398 |
+
shutil.rmtree(WORK, ignore_errors=True)
|
| 399 |
+
|
| 400 |
+
|
| 401 |
+
if __name__ == '__main__':
|
| 402 |
+
main()
|
model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:f14d62eff2fd75d55322ecce26b5b38818f9fd66a155370551fdaad93d86278b
|
| 3 |
+
size 1119825632
|
modules.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"idx": 0,
|
| 4 |
+
"name": "0",
|
| 5 |
+
"path": "",
|
| 6 |
+
"type": "sentence_transformers.base.modules.transformer.Transformer"
|
| 7 |
+
},
|
| 8 |
+
{
|
| 9 |
+
"idx": 1,
|
| 10 |
+
"name": "1",
|
| 11 |
+
"path": "1_Pooling",
|
| 12 |
+
"type": "sentence_transformers.sentence_transformer.modules.pooling.Pooling"
|
| 13 |
+
},
|
| 14 |
+
{
|
| 15 |
+
"idx": 2,
|
| 16 |
+
"name": "2",
|
| 17 |
+
"path": "2_Normalize",
|
| 18 |
+
"type": "sentence_transformers.base.modules.normalize.Normalize"
|
| 19 |
+
}
|
| 20 |
+
]
|
sentence_bert_config.json
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"transformer_task": "feature-extraction",
|
| 3 |
+
"modality_config": {
|
| 4 |
+
"text": {
|
| 5 |
+
"method": "forward",
|
| 6 |
+
"method_output_name": "last_hidden_state"
|
| 7 |
+
}
|
| 8 |
+
},
|
| 9 |
+
"module_output_name": "token_embeddings"
|
| 10 |
+
}
|
tokenizer.json
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:883b037111086fd4dfebbbc9b7cee11e1517b5e0c0514879478661440f137085
|
| 3 |
+
size 17082987
|
tokenizer_config.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"add_prefix_space": true,
|
| 3 |
+
"backend": "tokenizers",
|
| 4 |
+
"bos_token": "<s>",
|
| 5 |
+
"clean_up_tokenization_spaces": true,
|
| 6 |
+
"cls_token": "<s>",
|
| 7 |
+
"eos_token": "</s>",
|
| 8 |
+
"is_local": true,
|
| 9 |
+
"mask_token": "<mask>",
|
| 10 |
+
"max_length": 512,
|
| 11 |
+
"model_max_length": 512,
|
| 12 |
+
"pad_to_multiple_of": null,
|
| 13 |
+
"pad_token": "<pad>",
|
| 14 |
+
"pad_token_type_id": 0,
|
| 15 |
+
"padding_side": "right",
|
| 16 |
+
"sep_token": "</s>",
|
| 17 |
+
"stride": 0,
|
| 18 |
+
"tokenizer_class": "XLMRobertaTokenizer",
|
| 19 |
+
"truncation_side": "right",
|
| 20 |
+
"truncation_strategy": "longest_first",
|
| 21 |
+
"unk_token": "<unk>"
|
| 22 |
+
}
|