GLiNER v2 60M边缘小模型

GLiNER v2 60M边缘小模型
AI编程/Vibe Coding 遇到问题需要帮助的,联系微信 ezpoda,免费咨询。

让我们实事求是。你在炫目的幻灯片中看到的大多数"边缘 AI"解决方案都是谎言。

它们作为原型可以工作,但随后就崩溃了!你看过演示:一个小模型识别出"Apple"是公司,"Steve Jobs"是人。每个人都鼓掌。但当你将该模型投入到现实世界的生产环境中,例如,在专利中识别罕见的 PFAS 化学物质或从混乱的历史档案中提取 18 世纪的"isAt"关系时,它就会崩溃。

它撞上了"泛化墙"。

科技界每当新的 70B 模型发布时都会兴奋不已,但对于那些负担不起订阅或 4 万美元 H100 集群的人来说,现实是黯淡的。小模型(6000 万到 5 亿参数)历史上一直"很笨",因为它们被饿死了。我们给了它们 100 万个示例,并期望它们理解世界。

None

这不是通常的"越大越好"的论点。这一次,它关乎智能的密度。我们生活在一个荒谬的时间线中,我们期望一个 JPEG 大小的模型能像博士一样推理。但是等等。有一种出路。

1、60 亿 Token: NER 的"核选项"

又一则新闻。但这一条对那些在一线工作的人来说确实很重要。

GLiNER 团队刚刚投下了一枚重磅炸弹。他们不仅仅是调整架构;他们将数据按数量级扩展。我们说的是 60 亿个 NER 注释文本 token,用于训练一个只有 6000 万参数的模型。

想想这个比例。

大多数大语言模型(LLM)都在数万亿个 token 上训练,但它们有数十亿个参数来"存储"这些知识。当你将 60 亿个高质量、实体密集的数据 token 塞进一个 6000 万参数的模型时,神奇的事情就会发生:泛化。

为什么 100 万个示例还不够

  • 模式模仿: 在有限数据上训练的小模型学习识别"大写单词 + Inc."作为公司。它们没有学习公司的概念;它们在模仿排版模式。
  • 模式脆弱性: 如果标签从"Organization"变为"Firm",模型就会卡住。
  • 零样本差距: 如果它在训练期间没有看到特定的实体类型,F1 分数就会直线下降。

坦率地说,扩展到 60 亿 token 是从"模仿模式"转向"内化模式"的唯一途径。这是自那时以来第一项真正通过暴力数据质量来解决"边缘差距"的研究。

2、130 倍加速: Bi-Encoder 是优势

问题是这样的:速度不仅仅关乎 token 传播的速度。它关乎搜索的架构。

标准的命名实体识别(NER)经常使用 uni-encoder。你将文本和实体提示(标签)一起输入。这是计算昂贵的。如果你有 1,000 种实体类型,模型必须一遍又一遍地处理该上下文。

但如果你要在树莓派或移动设备上部署,你就没有"浪费"计算的奢侈。

3、进入 GLiNER-bi-Encoder

转向 bi-encoder 架构是快速且灵活的。通过将实体编码与文本编码解耦,GLiNER-bi-Encoder 在处理 1024 种实体类型时实现了 130 倍的速度提升。

按回车或点击以全尺寸查看图像(如果你的大脑甚至能可视化这种飞跃)。

  • Uni-Encoder: 文本 + 标签:一次大的、缓慢的计算。
  • Bi-Encoder: [文本] + [预计算标签]: 快速点积匹配。

不是大小,而是架构。这允许模型在精细的向量空间中表示数百万可能的实体。这就是你构建一个在现实世界中真正适用于实体链接的 GLinker 框架的方法,而不仅仅是在精心策划的基准测试中。

GitHub - fastino-ai/GLiNER2: Unified Schema-Based Information Extraction

4、当目标不是我赢,而是你输时(基准测试神话)

谁还相信这些标准化测试?我很愤世嫉俗。你也应该如此。大多数基准测试是"启发式旋钮调优练习"。它们不反映日常应用。

在现实世界中,我们处理"HIPE-2026"风格的问题:从嘈杂、多语言的历史文本中提取关系。我们处理"isAt"与"at"的区别,这需要时序推理。在清洁的新闻数据集上得分 99% 的模型在看到来自 19 世纪报纸的 OCR 错误的那一刻就会失败。

5、"停止思考"问题

我们生活在一个特殊的时间线中,我们终于意识到"更多计算"并不总是答案。

关于 SAGE(自感知引导高效推理)的新研究表明,大型推理模型(LRM)实际上知道它们何时已经解决了问题。它们隐式地知道何时停止思考。但我们当前的采样方法("解码层")是如此原始,以至于我们强迫模型继续空转。

抱歉,但这浪费了能源和金钱。

如果生活这么容易,我们只需要扔更多的 GPU 就可以了。但是等等。如果模型知道它完成了,为什么我们仍然将解码视为"启发式旋钮调优练习"?我们需要将解码视为一个原则性的优化层。这就是我们让边缘模型表现像巨型模型的方法。

6、GLinker 框架: 链接数百万

找到一个名称是一回事;知道它是哪个名称是另一回事。

GitHub - Knowledgator/GLinker: Efficient and scalable zero-shot entity linking

与 GLiNER-bi-V2 一起开发的 GLinker 框架,使用共享编码器来处理标签和内容。这细化了向量空间。这不仅仅是找到"巴黎";这是知道它是法国的巴黎,还是帕丽斯·希尔顿。

当你有数百万个实体时,你不能使用 uni-encoder。你会等到宇宙热寂才能得到响应。bi-encoder 方法使这在边缘成为可能。

为什么这很重要:

  • 隐私: 在本地处理一切。没有数据离开设备。
  • 延迟: 130 倍加速意味着实时交互,而不是"等待云端"的空转。
  • 成本: 6000 万参数可以在烤面包机上运行。你不需要每月 2,000 美元的 API 账单。

7、现实检验

让我们不要得意忘形。创新总是会带来新问题。当然,60 亿 token 有助于泛化,但总是有一个但是。

仅仅扩展数据可能导致"模仿"而不是真正的"内化"。正如在源 2 中看到的那样,文化能力需要的不仅仅是扩展单语数据。如果你的 60 亿 token 都来自西方网络抓取,你的 6000 万模型仍然会对全球南方的细微差别"文化盲目"。

我们不能只是抓取互联网并将其称为"智能"。

然后是硬件。虽然 GLiNER-bi-Encoder 很快,但在某些边缘部署中,缺乏像 Flash Attention 这样的硬件级优化仍然可能成为瓶颈。如果这不是它……那么是什么?

真正的故事不是大小。它是表示的效率。

8、"具身"连接

为什么我要同时谈论 NER 和机器人?

因为"边缘"是它们相遇的地方。无论是使用 EgoPush 重新排列物体而不需要全局坐标的机器人,还是从本地摄像头源提取实体的 6000 万 GLiNER 模型;约束都是相同的。

  • 没有全局状态。
  • 有限的计算。
  • 需要"主动感知"。

扩展现实(XR)的当前视频世界模型失败了,因为它们缺乏空间意识。它们是"断开的头"。它们使用像文本这样的粗粒度控制信号。我们需要能够响应追踪的现实世界运动的模型。

就像 GLiNER 需要 60 亿 token 来"理解"实体一样,具身 AI 需要"DeepVision-103K"风格的数据集来从 2D 输入中理解 3D 结构。这全都在于弥合"看见"和"理解"之间的差距。

9、如何真正为边缘构建

如果你是首席工程师或做出决策的 CXO,这里有一个蓝图。不要陷入"只使用 API"的陷阱。

  • 停止过度参数化: 如果你可以用 6000 万参数做,不要用 70 亿。碳足迹和延迟不值得那 1% 的 F1 增益。
  • 投资数据密度: 100 万个示例是玩具。60 亿 token 是工具。如果你在微调,专注于注释的质量规模,而不是模型的大小。
  • Bi-Encoder 赢: 如果你的任务涉及将文本与大型标签集匹配(NER、链接、分类),bi-encoder 是你最好的朋友。130 倍加速不是拼写错误。
  • 注意解码: 不要只使用默认的 Top-P 采样。研究像 SAGE 这样的优化层。效率在于"停止思考"的时刻。

10、GLiNER2 实体提取教程(来自仓库)

学习如何使用 GLiNER2 的灵活实体识别功能从文本中提取命名实体。

10.1 基本实体提取

from gliner2 import GLiNER2
# 加载模型
extractor = GLiNER2.from_pretrained("your-model-name")
# 提取常见实体
text = "Apple Inc. CEO Tim Cook announced the new iPhone 15 in Cupertino, California on September 12, 2023."
results = extractor.extract_entities(
    text,
    ["company", "person", "product", "location", "date"]
)
print(results)
# Output: {
#     'entities': {
#         'company': ['Apple Inc.'],
#         'person': ['Tim Cook'],
#         'product': ['iPhone 15'],
#         'location': ['Cupertino', 'California'],
#         'date': ['September 12, 2023']
#     }
# }

10.2 使用模式构建器

# 使用模式进行相同的提取
schema = extractor.create_schema().entities([
    "company", "person", "product", "location", "date"
])
results = extractor.extract(text, schema)

10.3 带描述的实体提取

描述通过提供上下文显著提高提取准确性。

# 医疗实体提取
schema = extractor.create_schema().entities({
    "drug": "Pharmaceutical drugs, medications, or treatment names",
    "disease": "Medical conditions, illnesses, or disorders",
    "symptom": "Clinical symptoms or patient-reported symptoms",
    "dosage": "Medication amounts like '50mg' or '2 tablets daily'",
    "organ": "Body parts or organs mentioned in medical context"
})
medical_text = """
Patient was prescribed Metformin 500mg twice daily for Type 2 Diabetes.
She reported fatigue and occasional dizziness. Liver function tests ordered.
"""
results = extractor.extract(medical_text, schema)
print(results)
# Output: {
#     'entities': {
#         'drug': ['Metformin'],
#         'disease': ['Type 2 Diabetes'],
#         'symptom': ['fatigue', 'dizziness'],
#         'dosage': ['500mg twice daily'],
#         'organ': ['Liver']
#     }
# }

10.4 单个与多个实体

控制是提取每个类型的一个还是多个实体。

# 默认行为 - 提取所有匹配的实体
schema = extractor.create_schema().entities(
    ["person", "organization"],
    dtype="list"  # 默认
)
text = "Bill Gates and Steve Jobs founded Microsoft and Apple respectively."
results = extractor.extract(text, schema)
# Output: {
#     'entities': {
#         'person': ['Bill Gates', 'Steve Jobs'],
#         'organization': ['Microsoft', 'Apple']
#     }
# }

10.5 每种类型单个实体

# 每种实体类型仅提取最佳匹配
schema = extractor.create_schema().entities(
    ["company", "ceo"],
    dtype="str"  # 单个实体模式
)
text = "Apple CEO Tim Cook met with Microsoft CEO Satya Nadella."
results = extractor.extract(text, schema)
# Output: {
#     'entities': {
#         'company': 'Apple',  # 只有一个,尽管文本中有多个
#         'ceo': 'Tim Cook'    # 只有一个
#     }
# }

10.6 自定义阈值

设置置信度阈值以进行精确控制。

# 高精度提取
results = extractor.extract_entities(
    text,
    ["email", "phone", "address"],
    threshold=0.8  # 需要高置信度
)

10.7 带置信度分数和字符位置

你可以使用 include_confidenceinclude_spans 参数包含置信度分数和字符级开始/结束位置:

# 提取带置信度分数的实体
text = "Apple Inc. CEO Tim Cook announced iPhone 15 in Cupertino."
results = extractor.extract_entities(
    text,
    ["company", "person", "product"],
    include_confidence=True
)
print(results)
# Output: {
#     'entities': {
#         'company': [
#             {'text': 'Apple Inc.', 'confidence': 0.95},
#             {'text': 'Tim Cook', 'confidence': 0.92}
#         ],
#         'product': [
#             {'text': 'iPhone 15', 'confidence': 0.88}
#         ]
#     }
# }

# 提取带字符位置(跨度)
results = extractor.extract_entities(
    text,
    ["company", "person"],
    include_spans=True
)
print(results)
# Output: {
#     'entities': {
#         'company': [
#             {'text': 'Apple Inc.', 'start': 0, 'end': 9}
#         ],
#         'person': [
#             {'text': 'Tim Cook', 'start': 15, 'end': 23}
#         ]
#     }
# }
# 提取带置信度和跨度
results = extractor.extract_entities(
    text,
    ["company", "product"],
    include_confidence=True,
    include_spans=True
)
print(results)
# Output: {
#     'entities': {
#         'company': [
#             {'text': 'Apple Inc.', 'confidence': 0.95, 'start': 0, 'end': 9}
#         ],
#         'product': [
#             {'text': 'confidence': 0.88, 'start': 15, 'end': 24}
#         ]
#     }
# }

注意:当 include_spans 为 True 时,输出格式会改变:

  • 默认(两者都为 False):返回简单的文本字符串:['Apple Inc.', 'Tim Cook']
  • include_confidence=True:返回带有 {'text': '...', 'confidence': 0.95} 的字典
  • include_spans=True:返回带有 {'text': '…', 'start': 0, 'end': 9} 的字典
  • 两者都为 True:返回带有 {'text': '…', 'confidence': 0.95, 'start': 0, 'end': 9} 的字典

10.8 每个实体的阈值

# 不同实体使用不同阈值
schema = extractor.create_schema().entities({
    "email": {
        "description": "Email addresses",
        "dtype": "list",
        "threshold": 0.9  # 邮箱的非常高的精度
    },
    "phone": {
        "description": "Phone numbers including mobile and landline",
        "dtype": "list",
        "threshold": 0.7  # 中等阈值
    },
    "name": {
        "description": "Person names",
        "dtype": "list",
        "threshold": 0.5  # 名称的较低阈值
    }
})
contact_text = "Contact John Doe at john.doe@email.com or call 555-1234."
results = extractor.extract(contact_text, schema, threshold=0.6)  # 默认阈值

10.9 高级配置和混合配置

# 组合不同的实体配置
schema = extractor.create_schema()
# 添加简单实体
schema.entities(["date", "time", "currency"])
# 添加带描述的实体
schema.entities({
    "technical_term": "Technical jargon or specialized terminology",
    "metric": "Measurements, KPIs, or quantitative values"
})
# 添加带完整配置的实体
schema.entities({
    "competitor": {
        "description": "Competing companies or products",
        "dtype": "list",
        "threshold": 0.7
    },
    "revenue": {
        "description": "Revenue figures or financial amounts",
        "dtype": "str",  # 仅提取一个
        "threshold": 0.8
    }
})

10.10 增量实体添加

# 增量构建模式
schema = extractor.create_schema()
# 分阶段添加实体
schema.entities(["person", "location"])  # 基本实体
schema.entities({"company": "Company or organization names"})  # 带描述
schema.entities({  # 带完整配置
    "financial_term": {
        "description": "Financial instruments, metrics, or terminology",
        "threshold": 0.75
    }
})

10.11 特定领域的实体(法律)

legal_schema = extractor.create_schema().entities({
    "party": "Parties involved in legal proceedings (plaintiff, defendant, etc.)",
    "law_firm": "Law firm or legal practice names",
    "court": "Court names or judicial bodies",
    "statute": "Legal statutes, laws, or regulations cited",
    "case": "Legal case names or citations",
    "judge": "Names of judges or magistrates",
    "legal_term": "Legal terminology or concepts"
})
legal_text = """
In the case of Smith v. Jones, Judge Sarah Williams of the Superior Court
ruled that the defendant violated Section 15.2 of the Consumer Protection Act.
The plaintiff was represented by Miller & Associates.
"""
results = extractor.extract(legal_text, legal_schema)

10.12 金融实体

finance_schema = extractor.create_schema().entities({
    "ticker": "Stock ticker symbols (e.g., AAPL, GOOGL)",
    "financial_metric": "Financial metrics like P/E ratio, market cap",
    "currency_amount": "Monetary values with currency symbols",
    "percentage": "Percentage values (e.g., 5.2%, -3%)",
    "financial_org": "Banks, investment firms, financial institutions",
    "market_index": "Stock market indices (S&P 500, NASDAQ, etc.)"
})
finance_text = """
AAPL rose 3.5% to $185.50 after beating earnings expectations.
The company's P/E ratio of 28.5 attracted Goldman Sachs analysts.
The NASDAQ composite gained 1.2% for the day.
"""
results = extractor.extract(finance_text, finance_schema)

10.13 科学实体

science_schema = extractor.create_schema().entities({
    "chemical": "Chemical compounds or elements",
    "organism": "Biological organisms, species names",
    "gene": "Gene names or identifiers",
    "measurement": "Scientific measurements with units",
    "research_method": "Research techniques or methodologies",
    "institution": "Universities or research institutions"
})
science_text = """
Researchers at MIT discovered that the BRCA1 gene mutation increases
cancer risk by 70%. The study used CRISPR-Cas9 to modify DNA sequences
in Mus musculus specimens, measuring tumor growth in millimeters.
"""
results = extractor.extract(science_text, science_schema)

10.14 最佳实践

1. 使用描述性实体名称

# 好 - 清晰、特定的实体类型
schema.entities(["drug_name", "medical_device", "procedure_name"])
# 不太理想 - 太通用
schema.entities(["thing", "item", "stuff"])

2. 通过描述提供上下文

# 好 - 清晰的描述
schema.entities({
    "acquisition_company": "Company that is acquiring another company",
    "target_company": "Company being acquired",
    "acquisition_price": "Purchase price or valuation of acquisition"
})
# 不太理想 - 没有上下文
schema.entities(["company1", "company2", "price"])

11、结论: 你有一个选择

我们生活在一个荒谬的时间线中,我们有比理智更多的计算能力。

当然生活是不公平的,但这并不意味着我们需要接受 OpenAI 或 Google 的"炒作机器"告诉我们的一切。你不需要数万亿参数来从文档中提取日期。你需要一个训练有素的、高密度的边缘模型,它不会浪费它的"思考时间"。

60 亿 token 的 GLiNER 模型是对小模型本质上受限这一观点的震动。它证明,只要有足够的高质量数据和正确的架构,边缘可以在"日常应用"中胜过云端。

如果你是决策者,停止为"特定目的"任务向"通用目的"巨型模型扔钱。这是低效的;这是昂贵的;坦率地说,这是懒惰的工程。

通过专注于数据与参数的比例来改进系统。要求模型"知道何时停止思考"。构建能够本地、私密、即时工作的系统。

这是我的观点。你应该做你感到舒适的事情。但如果你还在等待一个 1000 亿参数的模型来告诉你"Person"实体在句子中的位置……

我们是认真的吗?走向边缘。扩展数据,而不是权重。

最后的想法:

下次有人告诉你 AI 中"大小很重要"时,向他们展示一个在 60 亿 token 上训练的 6000 万模型。然后看着他们试图解释为什么他们的每月 20 美元订阅仍在"思考"一个简单的 NER 任务。

哦!检查你的解码参数。你的模型可能已经完成了;你只是没有在倾听。


原文链接: GLiNER v2 60M: A Model For Edge AI!

汇智网翻译整理,转载请标明出处