Sentence Similarity
sentence-transformers
ONNX
Safetensors
Chinese
modernbert
embeddings
clinical
healthcare
traditional-chinese
taiwan
medical
fhir
on-premise
text-embeddings-inference
Instructions to use weemed/IlhaEmbed with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- sentence-transformers
How to use weemed/IlhaEmbed with sentence-transformers:
from sentence_transformers import SentenceTransformer model = SentenceTransformer("weemed/IlhaEmbed") sentences = [ "那是 個快樂的人", "那是 條快樂的狗", "那是 個非常幸福的人", "今天是晴天" ] embeddings = model.encode(sentences) similarities = model.similarity(embeddings, embeddings) print(similarities.shape) # [4, 4] - Notebooks
- Google Colab
- Kaggle
docs: definitive eval numbers (semantic macro 0.86); reframe taigi as a transliteration diagnostic (not a self-match bug), excluded from the macro with reason
3ddd653 verified | license: apache-2.0 | |
| language: | |
| - zh | |
| library_name: sentence-transformers | |
| pipeline_tag: sentence-similarity | |
| tags: | |
| - embeddings | |
| - clinical | |
| - healthcare | |
| - traditional-chinese | |
| - taiwan | |
| - medical | |
| - fhir | |
| - on-premise | |
| - onnx | |
| base_model: ibm-granite/granite-embedding-97m-multilingual-r2 | |
| # IlhaEmbed | |
| English | [繁體中文](#繁體中文) | |
| A small embedding model for Taiwanese clinical text. | |
| Clinical records in Taiwan are full of local shorthand. 斷腦筋 means stroke, 不辣咖 means a blood culture, H/T is hypertension, and V(H/T) means the patient is followed for hypertension at an outside clinic. General-purpose and general Chinese models mostly miss these, because they never saw how doctors, nurses, and care workers in Taiwan actually write. IlhaEmbed was trained for it. | |
| The name is from Ilha Formosa. It reads this island's clinical language. | |
| ## Highlights | |
| - **Reads local clinical writing.** Slang, abbreviations, Taigi, handwritten shorthand. Where a general model returns noise, this one usually returns the right concept. | |
| - **Runs on-premise.** 37 MB, INT8, CPU only. No GPU, no cloud, no API key. Patient data stays in the hospital. | |
| - **Clear provenance.** Apache-2.0 weights, a public and documented base model (IBM Granite ModernBERT), and a pipeline you can trace. Ready for a procurement or security review. | |
| - **Open and commercial-friendly.** Apache-2.0, no copyleft. | |
| ## What it is for | |
| Turning messy clinical text into structured meaning. Common uses: | |
| - Normalizing clinical text: mapping abbreviations and slang to standard concepts (H/T to 高血壓). | |
| - Placing dirty data: on import, reading one cell and sending each fact to the field it belongs in (medication, condition, care source, and so on). | |
| - Matching terms and codes: finding the right ICD, LOINC, or drug concept for a surface term. | |
| - Searching across fields: finding a record from the clue at hand, without knowing the exact field name. | |
| In a clinical pipeline built in Taiwan, it handles the "understanding" step: Breeze-ASR-26 for speech, IlhaEmbed for meaning, FHIR for structure. | |
| ## Results | |
| Task: jargon top-1. Given a Taiwanese clinical surface term, retrieve its standard concept from a shared pool, self-matches excluded, held out from training. The score is macro-averaged over three semantic registers — slang, abbreviation, and apposition — where each surface form maps to a standard Han concept (斷腦筋→中風, Tid→一天三次, URI→上呼吸道感染). All models use the same method and the same pool; numbers are from the reproducible `card_eval_cpu.py`. | |
| | Model | On-prem | slang | abbrev | apposition | semantic macro | | |
| |---|---|---|---|---|---| | |
| | **IlhaEmbed** | yes, 37 MB CPU | **0.86** | **0.82** | **0.89** | **0.86** | | |
| | jina-embeddings-v2-base-zh | no | 0.05 | 0.14 | 0.45 | 0.21 | | |
| | ckip-base | yes | 0.00 | 0.01 | 0.36 | 0.13 | | |
| | bge-small-zh | yes | 0.00 | 0.00 | 0.33 | 0.11 | | |
| On these local terms the general and general-Chinese models mostly return nothing; this model finds the right concept. It is not meant to top general leaderboards such as MTEB. It does one thing, Taiwanese clinical vocabulary, and it is small enough to run on the ward. | |
| The method is reproducible. The raw evaluation pairs carry third-party copyright and are not redistributed. | |
| ### On Taigi, and why it is not folded into that number (nothing is hidden) | |
| A fourth set, `taigi_med_lexicon`, maps a Han term to its **Tâi-lô romanization** (中風 → tiong-hong). Every model, including this one, scores ~0.00 on it — and that is correct: mapping a Han term to a romanized spelling is a **transliteration** task, not semantic retrieval. It belongs to a romanization / ASR model, not a meaning embedder, so it is reported as a diagnostic and kept **out of the semantic macro**; averaging a transliteration score into a semantic benchmark would only produce a meaningless number. (An earlier version of this card called the ~0 a "self-match bug" — that was wrong; only 31/779 surfaces collide with the pool and those are already excluded. The ~0 is the task mismatch.) | |
| The embedder's **Taigi clinical capability is already in the numbers above**: the `slang` register *is* that capability — Taiwanese clinical colloquialisms (斷腦筋 for stroke, 不辣咖 for a blood culture) mapped to their standard concepts, at 0.86. A dedicated Taigi-colloquial → standard-Han-concept set (Han→Han, semantic) is the natural next benchmark to add. | |
| ## Usage | |
| ```python | |
| # ONNX (deployment path, no torch, CPU) | |
| from tokenizers import Tokenizer | |
| import onnxruntime as ort, numpy as np | |
| tok = Tokenizer.from_file("tokenizer.json") | |
| sess = ort.InferenceSession("model_int8.onnx") | |
| # encode (max_len 32), run, mean-pool, L2-normalize, giving a 384-d vector | |
| ``` | |
| ```python | |
| # sentence-transformers (research path) | |
| from sentence_transformers import SentenceTransformer | |
| model = SentenceTransformer("weemed/IlhaEmbed") | |
| model.encode(["斷腦筋", "H/T", "定期心內門診-戒菸"]) | |
| ``` | |
| 384 dimensions, up to 32 tokens. Vocab 25.5k (pruned to Traditional Chinese and clinical). Size 37 MB (INT8 ONNX) or 152 MB (fp32 safetensors). | |
| ## How it was built | |
| The base model is IBM Granite ModernBERT (Apache-2.0), permissively licensed. A Taiwanese clinical teacher signal supplies the domain knowledge through knowledge distillation, so the student learns to place Taiwanese slang, abbreviations, and Taigi next to their standard concepts. | |
| The base model ships a 180k multilingual BPE vocabulary, most of which Traditional Chinese clinical text never uses. Pruning it to the 25.5k tokens that actually appear cut the size by 68 percent (117 MB to 37 MB) with no loss of accuracy: jargon top-1 held, and the real import routing came out bit-identical. | |
| ## Intended use and limits | |
| This is a tool for semantic representation, not a diagnostic system. It offers likely meanings and matches for a person to confirm, and does not decide clinical facts on its own. It is tuned for Traditional Chinese clinical text in Taiwan. General prose and Simplified Chinese are out of scope. | |
| ## License | |
| Apache-2.0. Base model: IBM Granite (Apache-2.0). Training-pair sources are listed in `SOURCES.md`. What we release is the trained weights, a distributable derivative; the raw third-party pairs are not included. | |
| --- | |
| <a name="繁體中文"></a> | |
| # IlhaEmbed(繁體中文) | |
| [English](#ilhaembed) | 繁體中文 | |
| 一個讀得懂台灣臨床文字的小型語意模型。 | |
| 台灣的病歷、備註、社區照護表上,有很多在地的寫法。斷腦筋是中風,不辣咖是血液培養,H/T 是高血壓,V(H/T) 是這位病人在外院追蹤高血壓。這些寫法,通用模型和一般中文模型多半讀不出來,因為它們沒看過台灣的醫師、護理師、照服員實際怎麼寫。IlhaEmbed 是針對這件事訓練的。 | |
| 名字取自 Ilha Formosa。它專門讀這座島的臨床語言。 | |
| ## 特點 | |
| - **讀得懂在地的臨床寫法。** 行話、縮寫、台語、手寫簡寫。通用模型讀成雜訊的地方,它多半能對到正確的概念。 | |
| - **完全在地端。** 37 MB、INT8、純 CPU。不用 GPU、雲端或 API key,病人資料不離開院內。 | |
| - **來源清楚。** Apache-2.0 權重,基礎模型是公開、有文件的 IBM Granite ModernBERT,訓練流程可追溯。採購或資安要看,都拿得出來。 | |
| - **開源、可商用。** Apache-2.0,沒有 copyleft 的限制。 | |
| ## 用途 | |
| 把凌亂的臨床文字整理成有結構的意義。常見的用法: | |
| - 臨床文字正規化:把縮寫、行話對到標準概念(H/T 對到高血壓)。 | |
| - 髒資料歸位:匯入時讀一格內容,把裡面每個事實送到該去的欄位(用藥、疾病、就醫來源等)。 | |
| - 術語、代碼比對:幫一個詞找到對應的 ICD、LOINC 或藥品概念。 | |
| - 跨欄位搜尋:用手上僅有的線索找到紀錄,不必先知道正確的欄位名稱。 | |
| 在一條台灣自己的臨床流程裡,它負責「理解」這一段:Breeze-ASR-26 聽打,IlhaEmbed 理解,FHIR 存成結構。 | |
| ## 成效 | |
| 測的是 jargon top-1:給一個台灣臨床的表面詞,從共用概念池裡找出對應的標準概念,排除自我匹配,且留作測試。分數是**三個語意語域**(行話 slang、縮寫 abbrev、同位語 apposition)的平均,每個都是「口語/台語/縮寫的漢字表面詞 → 標準漢字概念」(斷腦筋→中風、Tid→一天三次、URI→上呼吸道感染)。四個模型用同一套方法、同一個池;數字來自可重現的 `card_eval_cpu.py`。 | |
| | 模型 | 在地端 | slang | abbrev | apposition | 語意 macro | | |
| |---|---|---|---|---|---| | |
| | **IlhaEmbed** | 是,37 MB CPU | **0.86** | **0.82** | **0.89** | **0.86** | | |
| | jina-embeddings-v2-base-zh | 否 | 0.05 | 0.14 | 0.45 | 0.21 | | |
| | ckip-base | 是 | 0.00 | 0.01 | 0.36 | 0.13 | | |
| | bge-small-zh | 是 | 0.00 | 0.00 | 0.33 | 0.11 | | |
| 在這些在地詞彙上,通用模型和一般中文模型多半讀不出來,這個模型能對到正確概念。它不是要在通用排行榜(MTEB)上比高下,只把台灣臨床詞彙這一件事做好,而且小到能在病房的機器上跑。 | |
| 這套方法可以重現。原始的評估配對有第三方著作權,不隨模型散佈。 | |
| ### 關於台語,以及為什麼它不併進上面那個數字(沒有藏任何東西) | |
| 還有第四個集 `taigi_med_lexicon`,它是把漢字詞對到它的**台羅羅馬字**(中風 → tiong-hong)。所有模型(包含這個)在上面都是 ~0.00 —— 而這是**對的**:把漢字對到羅馬拼寫是**音譯**任務、不是語意檢索,那是羅馬字/ASR 模型的工作、不是語意 embedder 的工作。所以它只當診斷用、**不併進語意 macro**;把音譯分數平均進語意 benchmark 只會得到一個沒有意義的數字。(這張 card 之前把那個 ~0 稱作「self-match bug」,那是錯的;只有 31/779 的表面詞會撞到池子、而且早就被排除,~0 是任務錯配。) | |
| 這個模型的**台語臨床能力其實就在上面的數字裡**:`slang` 語域正是它 —— 台灣臨床口語(斷腦筋=中風、不辣咖=血液培養)對到標準概念,0.86。之後自然要補的是一個專門的「台語口語 → 標準漢字概念」(漢字→漢字、語意)測試集。 | |
| ## 用法 | |
| ```python | |
| # ONNX(部署路徑,不需 torch、CPU) | |
| from tokenizers import Tokenizer | |
| import onnxruntime as ort, numpy as np | |
| tok = Tokenizer.from_file("tokenizer.json") | |
| sess = ort.InferenceSession("model_int8.onnx") | |
| # 編碼(max_len 32)、推論、mean-pool、L2 normalize,得到 384 維向量 | |
| ``` | |
| ```python | |
| # sentence-transformers(研究路徑) | |
| from sentence_transformers import SentenceTransformer | |
| model = SentenceTransformer("weemed/IlhaEmbed") | |
| model.encode(["斷腦筋", "H/T", "定期心內門診-戒菸"]) | |
| ``` | |
| 維度 384,最長 32 個 token。詞表 25.5k(剪過,只留繁體中文和臨床會用到的)。大小 37 MB(INT8 ONNX)或 152 MB(fp32 safetensors)。 | |
| ## 怎麼做的 | |
| 基礎模型用 IBM Granite ModernBERT(Apache-2.0),授權寬鬆。用台灣臨床的 teacher 訊號做知識蒸餾,讓學生模型學會把台灣的行話、縮寫、台語,擺到對應的標準概念旁邊。 | |
| 基礎模型原本帶 18 萬詞的多語 BPE 詞表,繁中臨床大多用不到。把它剪到實際會用到的 25.5k,體積少了 68%(117 MB 到 37 MB),準確度沒掉:jargon top-1 一樣,實際跑匯入的路由結果逐位相同。 | |
| ## 適用範圍 | |
| 這是一個做語意表示的工具,不是診斷系統。它給的是可能的意義和比對,最後由人確認,不會自己下臨床判斷。它針對台灣的繁體中文臨床文字調過,一般文章或簡體中文不在範圍內。 | |
| ## 授權 | |
| Apache-2.0。基礎模型 IBM Granite(Apache-2.0)。訓練配對的來源記在 `SOURCES.md`。釋出的是訓練後的權重(可散佈的衍生成果),原始的第三方配對不隨附。 | |