Models
EN/AR → urchade/gliner_multi-v2.1 (GLiNER zero-shot, ~1 GB, ~500 ms)
ZH → shibing624/bert4ner-base-chinese (BERT NER, ~400 MB, ~100 ms)
mixed → both models run in parallel, results merged + deduplicated
Language detection (app/ner.py)
Layer-1 Unicode script ratio (CJK / Arabic / Latin)
mixed = cjk>=8% AND latin>=10% (prevents dominant-CJK from
masking bilingual text)
Layer-2 langdetect n-gram fallback when Layer-1 returns 'en'
Fallback / merge (NERService.extract)
zh primary=BERT, fallback=GLiNER when entities==0
en/ar primary=GLiNER, fallback=BERT when entities==0
mixed run both, _deduplicate keeps highest-score per (start,end) span
Other changes
app/config.py EN_MODEL_NAME / ZH_MODEL_NAME env vars; legacy MODEL_NAME kept
app/labels.py BERT_TYPE_TO_LABEL, LABEL_TO_BERT_TYPES, labels_to_bert_types()
requirements.txt add transformers>=4.40.0, langdetect>=1.0.9
Dockerfile pre-download both models at build …
feat: switch to knowledgator/gliner-multitask-large-v0.5 for multilingual NER
Robin+1: Claude Sonnet 4.6
3cb6d87
urchade/gliner_medium-v2.1 is English-only — Chinese entities (persons,
orgs, locations) were almost entirely missed. The multitask-large model
supports zh/en/ar and other languages out of the box.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
refactor: remove httpx proxy, call GLiNER model directly
Robin+1: Claude Sonnet 4.6
bfeb704
- ner.py: restored GLiNER.from_pretrained with cache_dir
- config.py: restored MODEL_NAME, MODEL_CACHE_DIR, HF_ENDPOINT
- main.py: pass MODEL_NAME and MODEL_CACHE_DIR to NERService
- requirements.txt: replaced httpx with gliner
- conftest.py: restored gliner/torch stubs for unit tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fix: separate proxy port (4000) from upstream GLiNER port (4001)
Robin+1: Claude Sonnet 4.6
56305a3
NER_API_BASE_URL was pointing to the same port as the proxy,
causing a circular call: proxy → itself → 404 → 502.
Upstream GLiNER service now defaults to port 4001.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fix: add /api/v1 prefix and restore port 4000
Robin+1: Claude Sonnet 4.6
9a7f7d0
- Routes changed to /api/v1/health and /api/v1/extract
- Default PORT reverted to 4000 (8000 was in use)
- conftest.py: remove gliner/torch stubs (ner.py now uses httpx)
- Tests updated to match new route prefix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
feat: add HF Spaces Docker deployment
Robin+1: Claude Sonnet 4.6
3a87a16
- Dockerfile: Python 3.11-slim, port 7860 (HF Spaces required)
- README.md: HF Spaces frontmatter (sdk: docker, app_port: 7860)
- config.py: HF_ENDPOINT only applied when explicitly set, so HF
Spaces reaches huggingface.co directly without the local mirror
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
feat: GLiNER NER HTTP API
Robin+1: Claude Sonnet 4.6
d470d45
- POST /extract 接收文本和实体类型,返回抽取结果
- 模型启动时加载一次,多次请求复用
- 通过 HF_ENDPOINT 使用国内镜像,MODEL_CACHE_DIR 本地缓存
- 默认端口 4000,支持环境变量配置
- 包含单元测试(mock)和集成测试(真实 API)
- start.bat 从 conda ai 环境启动
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>