# NeoMME

[![Hugging Face](https://img.shields.io/badge/Collection-FFD21E?style=for-the-badge&logo=huggingface&logoColor=000)](https://huggingface.co/collections/Hcompany/neomme)
[![arXiv](https://img.shields.io/badge/arXiv-2609.01657-b31b1b.svg?style=for-the-badge)](https://arxiv.org/abs/2609.01657)

NeoMME 是由 H Company 推出的一系列高效的 260M 和 800M 参数多模态原生多语言基础编码器。它在单个双向 Transformer 编码器中处理多语言文本标记和原始图像块，无需单独预训练的视觉塔或因果语言模型。

NeoMME-Retriever 是一个基于 NeoMME 主干模型微调的模型，用于视觉文档检索，同时采用晚期交互（late-interaction）和稠密（dense）目标。它接收文本查询和文档（文本或页面截图），并生成用于 MeanMaxSim 评分（晚期交互）的多向量嵌入，以及用于余弦相似度计算的均值池化嵌入（稠密）。

预训练骨干网络和检索检查点在 [NeoMME 集合](https://huggingface.co/collections/Hcompany/neomme) 中以 Apache 2.0 许可证提供，并可与 [Sentence Transformers](https://huggingface.co/sentence-transformers) 配合使用。

## 使用示例

**生成编码器隐藏状态**

```python
import requests
import torch
from PIL import Image

from transformers import AutoModel, AutoProcessor

def encode_document_text(processor, text: str) -> str:
    return f"{processor.tokenizer.document_token}{text}"

model_id = "Hcompany/NeoMME-260M"
processor = AutoProcessor.from_pretrained(model_id)
model = AutoModel.from_pretrained(model_id, device_map="auto")

text = "The cat sat on a mat."
image_url = "https://github.com/tonywu71/colpali-cookbooks/blob/main/examples/data/shift_kazakhstan.jpg?raw=true"
image = Image.open(requests.get(image_url, stream=True).raw)

inputs = processor(
    text=[
        encode_document_text(processor, text),
        encode_document_text(processor, processor.image_token),
    ],
    images=[image],
    padding=True,
    return_tensors="pt",
).to(model.device)

with torch.inference_mode():
    outputs = model(**inputs)

text_hidden_states, image_hidden_states = outputs.last_hidden_state
```

**掩码语言建模**

```python
import torch

from transformers import AutoModelForMaskedLM, AutoProcessor

model_id = "Hcompany/NeoMME-260M"
processor = AutoProcessor.from_pretrained(model_id)
model = AutoModelForMaskedLM.from_pretrained(model_id, device_map="auto")

# Equivalent: "<doc>The capital of <mask> is London."
text = f"{processor.tokenizer.document_token}The capital of {processor.tokenizer.mask_token} is London."
inputs = processor(text=[text], return_tensors="pt").to(model.device)

with torch.inference_mode():
    outputs = model(**inputs)

masked_index = (inputs.input_ids[0] == processor.tokenizer.mask_token_id).nonzero().item()
predicted_token_id = outputs.logits[0, masked_index].argmax(dim=-1)
print(processor.tokenizer.decode(predicted_token_id))
```

**视觉文档检索**

> [!IMPORTANT]
> 安装 `sentence-transformers>=6.0.0` 以在下面的检索示例中使用 MeanMaxSim 评分。有关 Sentence Transformers API，请参阅 [Multi-Vector Encoder 快速入门](https://sbert.net/docs/quickstart.html#multi-vector-encoder)。

```python
from typing import Any, Literal

import requests
import torch
from PIL import Image
from sentence_transformers.util import cos_sim, mean_maxsim

from transformers import BatchFeature, NeoMMEForRetrieval, NeoMMEProcessor

def encode(
    messages: list[list[dict[str, Any]]],
    task: Literal["query", "document"],
) -> BatchFeature:
    return processor.apply_chat_template(
        messages,
        task=task,
        tokenize=True,
        return_dict=True,
        return_tensors="pt",
        processor_kwargs={"padding": "longest"},
    )

model_name = "Hcompany/NeoMME-260M-Retriever"
processor = NeoMMEProcessor.from_pretrained(model_name)
model = NeoMMEForRetrieval.from_pretrained(model_name)

# Document images (our corpus)
image_urls = [
    "https://github.com/tonywu71/colpali-cookbooks/blob/6ef1332da6bcb48c7ef1f19b25bfa555be7031a8/examples/data/shift_kazakhstan.jpg?raw=true",
    "https://github.com/tonywu71/colpali-cookbooks/blob/6ef1332da6bcb48c7ef1f19b25bfa555be7031a8/examples/data/energy_electricity_generation.jpg?raw=true",
]
documents = [Image.open(requests.get(url, stream=True).raw) for url in image_urls]

# Queries
queries = [
    "Quelle partie de la production pétrolière du Kazakhstan provient de champs en mer ?",
    "Which hour of the day had the highest overall electricity generation in 2019?",
]

document_messages = [
    [{"role": "user", "content": [{"type": "image", "image": document}]}] for document in documents
]
query_messages = [[{"role": "user", "content": query}] for query in queries]

inputs_documents = encode(document_messages, "document").to(model.device)
inputs_text = encode(query_messages, "query").to(model.device)

with torch.inference_mode():
    document_outputs = model(**inputs_documents)
    query_outputs = model(**inputs_text)

late_scores = mean_maxsim(
    query_outputs.embeddings,
    document_outputs.embeddings,
    a_mask=inputs_text["attention_mask"],
    b_mask=inputs_documents["attention_mask"],
)
dense_scores = cos_sim(query_outputs.dense_embeddings, document_outputs.dense_embeddings)

# Expected: late_scores[0, 0] > late_scores[0, 1] and late_scores[1, 1] > late_scores[1, 0].
print(late_scores, dense_scores)
```

## NeoMMEConfig[[transformers.NeoMMEConfig]]

#### transformers.NeoMMEConfig[[transformers.NeoMMEConfig]]

```python
transformers.NeoMMEConfig(transformers_version: str | None = None, architectures: list[str] | None = None, output_hidden_states: bool | None = False, return_dict: bool | None = True, dtype: str | torch.dtype | None = None, chunk_size_feed_forward: int = 0, is_encoder_decoder: bool = False, id2label: dict[int, str] | dict[str, str] | None = None, label2id: dict[str, int] | dict[str, str] | None = None, problem_type: Literal['regression', 'single_label_classification', 'multi_label_classification'] | None = None, vocab_size: int = 131072, embedding_rank: int = 256, hidden_size: int = 1024, intermediate_size: int = 3584, hidden_act: typing.Literal['relu2'] = 'relu2', mlp_bias: bool = False, num_hidden_layers: int = 17, num_attention_heads: int = 16, num_key_value_heads: int = 4, head_dim: int = 64, max_position_embeddings: int = 16384, norm_eps: float = 1e-06, initializer_range: float = 0.02, attention_dropout: float | int = 0.0, attention_bias: bool = False, layer_types: list[str] | None = None, rope_parameters: dict[typing.Literal['full_attention', 'sliding_attention'], dict] | None = None, sliding_window: int | None = 256, residual_multiplier: float | None = None, patch_size: int = 32, embedding_dim: int = 128, pad_token_id: int | None = 0, document_token_id: int | None = 5, image_token_id: int | None = 6, tie_word_embeddings: bool = True)
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/neomme/configuration_neomme.py#L33)

**参数：**

vocab_size (`int`，*可选*，默认值为 `131072`)：模型的词汇表大小。定义了 `input_ids` 可以表示的不同 token 数量。

embedding_rank (`int`，*可选*，默认为 256)：投影到 `hidden_size` 之前，分解后的 token 嵌入表的宽度。

hidden_size (`int`，*可选*，默认为 `1024`)：隐藏表示的维度。

intermediate_size (`int`，*可选*，默认为 `3584`)：MLP 表示的维度。

hidden_act (`Literal[relu2]`，*可选*，默认为 `relu2`)：解码器中的非线性激活函数（函数或字符串）。例如，`"gelu"`、`"relu"`、`"silu"` 等。

mlp_bias (`bool`，*可选*，默认为 `False`)：是否在 MLP 层的 up_proj、down_proj 和 gate_proj 层中使用偏置。

num_hidden_layers (`int`，*可选*，默认为 `17`)：Transformer 解码器中的隐藏层数。

num_attention_heads (`int`，*可选*，默认为 `16`)：Transformer 解码器中每个注意力层的注意力头数量。

num_key_value_heads (`int`, *可选*，默认为 `4`) : 这是用于实现 Grouped Query Attention 的 key_value 头数量。如果 `num_key_value_heads=num_attention_heads`，模型将使用 Multi Head Attention (MHA)；如果 `num_key_value_heads=1`，模型将使用 Multi Query Attention (MQA)；否则将使用 GQA。在将多头检查点转换为 GQA 检查点时，每个组的 key 和 value 头应通过对该组内所有原始头进行平均池化来构建。更多详情请参阅 [这篇论文](https://huggingface.co/papers/2305.13245)。如果未指定，则默认为 `num_attention_heads`。

head_dim (`int`, *可选*, 默认为 `64`) : 注意力头维度。如果为 None，则默认为 hidden_size // num_attention_heads

max_position_embeddings (`int`，*可选*，默认值为 `16384`)：该模型可能使用的最大序列长度。

norm_eps (`float`, *可选*, 默认为 `1e-06`) : 层归一化层使用的 epsilon。

initializer_range (`float`，*可选*，默认值为 `0.02`)：用于初始化所有权重矩阵的 truncated_normal_initializer 的标准差。

attention_dropout (`Union[float, int]`，*可选*，默认值为 `0.0`)：注意力概率的 dropout 比率。

attention_bias (`bool`，*可选*，默认为 `False`)：在自注意力机制中，是否在查询、键、值和输出投影层中使用偏置。

layer_types (`list[str]`, *可选*) : 默认情况下，每第六层和最后一层使用完整注意力机制。

rope_parameters (`dict`, *可选*) : `"full_attention"` 和 `"sliding_attention"` 层的旋转位置设置。旋转维度 `head_dim * partial_rotary_factor` 必须是四的正整数倍。

sliding_window (`int`, *可选*，默认为 `256`)：滑动窗口注意力机制的窗口大小。如果为 `None`，则不应用滑动窗口。

residual_multiplier (`float`, *可选*) : 应用于注意力和 MLP 残差分支的缩放系数。默认值为 `1 / sqrt(2 * num_hidden_layers)`。

patch_size (`int`，*可选*，默认为 `32`)：每个 patch 的大小（分辨率）。

embedding_dim (`int`，*可选*，默认为 128)：[NeoMMEForRetrieval](/docs/transformers/main/zh/model_doc/neomme#transformers.NeoMMEForRetrieval) 返回的 token 级嵌入的宽度。此设置与 `embedding_rank` 无关。

pad_token_id (`int`，*可选*，默认为 `0`)：词表中用于填充的 Token ID。

document_token_id (`int`，*可选*，默认为 5)：`<doc>` 标记的 Token ID。

image_token_id (`int`，*可选*，默认为 `6`)：用作输入图像占位符的图像标记索引。

tie_word_embeddings (`bool`, *可选*, 默认为 `True`) : 掩码标记解码器是否同时复用两个分解的标记嵌入权重。

这是用于存储 NeoMMEModel 配置的类。它根据指定的参数实例化 Neomme 模型，并定义模型架构。使用默认值实例化配置将得到与 [Hcompany/NeoMME-260M](https://huggingface.co/Hcompany/NeoMME-260M) 类似的配置。

配置对象继承自 [PreTrainedConfig](/docs/transformers/main/zh/main_classes/configuration#transformers.PreTrainedConfig)，可用于控制模型输出。有关更多信息，请参阅 [PreTrainedConfig](/docs/transformers/main/zh/main_classes/configuration#transformers.PreTrainedConfig) 的文档。

```python
>>> from transformers import NeoMMEModel, NeoMMEConfig

>>> configuration = NeoMMEConfig()
>>> model = NeoMMEModel(configuration)
```

## NeoMMEImageProcessor[[transformers.NeoMMEImageProcessor]]

#### transformers.NeoMMEImageProcessor[[transformers.NeoMMEImageProcessor]]

```python
transformers.NeoMMEImageProcessor(**kwargs: *<class 'transformers.models.neomme.image_processing_neomme.NeoMMEImageProcessorKwargs'>)
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/neomme/image_processing_neomme.py#L107)

**参数：**

do_convert_rgb (`bool`，*kwargs*，*可选*，默认为 `True`)：是否将图像转换为 RGB。

do_resize (`bool`, *kwargs*, *可选*, 默认为 `True`) : 是否调整图像大小。

size (`Annotated[int | list[int] | tuple[int, ...] | dict[str, int] | None, None]`, *kwargs*，默认为 `None`)：描述模型的最大输入维度。

default_to_square (`bool`，*kwargs*，*可选*，默认为 `True`)：当 size 为整数时，是否在调整大小时默认使用正方形图像。

crop_size (`Annotated[int | list[int] | tuple[int, ...] | dict[str, int] | None, None]`, *kwargs*) : 应用 `center_crop` 后输出图像的尺寸。

resample (`Annotated[Union[int, PILImageResampling, NoneType], None]`, *kwargs*，默认为 `2`) : 如果调整图像大小，则使用的重采样滤波器。它可以是枚举 `PILImageResampling` 中的一个值。仅当 `do_resize` 设置为 `True` 时才会生效。

do_rescale (`bool`, *kwargs*, *可选*，默认为 `True`)：是否对图像进行重新缩放。

rescale_factor (`float`, *kwargs*, *可选*，默认为 `0.00392156862745098`) : 当 `do_rescale` 设置为 `True` 时，用于对图像进行缩放的缩放因子。

do_normalize (`bool`，*kwargs*，*可选*，默认为 `True`)：是否对图像进行归一化。

image_mean (`Union[float, list[float], tuple[float, ...]]`，*kwargs*，*可选*，默认为 `[0.5, 0.5, 0.5]`)：用于归一化的图像均值。仅当 `do_normalize` 设置为 `True` 时生效。

image_std (`Union[float, list[float], tuple[float, ...]]`, *kwargs*, *可选*，默认为 `[0.5, 0.5, 0.5]`) : 用于归一化的图像标准差。仅当 `do_normalize` 设置为 `True` 时生效。

do_pad (`bool`, *kwargs*, *可选*) : 是否对图像进行填充。填充操作会将图像填充至批次中的最大尺寸，或填充至每张图像的固定正方形尺寸。具体的填充策略取决于模型。

pad_size (`Annotated[int | list[int] | tuple[int, ...] | dict[str, int] | None, None]`, *kwargs*) : 用于将图像填充到的尺寸，格式为 `{"height": int, "width" int}`。该尺寸必须大于预处理中提供的任何图像尺寸。如果未提供 `pad_size`，图像将被填充到批次中最大的高度和宽度。仅在 `do_pad=True.` 时应用。

do_center_crop (`bool`, *kwargs*, *可选*) : 是否对图像进行居中裁剪。

data_format (`Union[str, ~image_utils.ChannelDimension]`，*kwargs*，*可选*)：仅支持 `ChannelDimension.FIRST`。为兼容旧版处理器而添加。

input_data_format (`Union[str, ~image_utils.ChannelDimension]`, *kwargs*, *可选*) : 输入图像的通道维度格式。如果未设置，则从输入图像中推断通道维度格式。可以是以下之一： - `"channels_first"` 或 `ChannelDimension.FIRST`：图像为 (num_channels, height, width) 格式。 - `"channels_last"` 或 `ChannelDimension.LAST`：图像为 (height, width, num_channels) 格式。 - `"none"` 或 `ChannelDimension.NONE`：图像为 (height, width) 格式。

device (`Annotated[Union[str, torch.device, NoneType], None]`, *kwargs*)：用于处理视频的设备。如果未设置，则从输入视频中推断设备。

return_tensors (`Annotated[str | ~utils.generic.TensorType | None, None]`, *kwargs*) : 如果设置为 `'pt'`，则返回堆叠的张量，否则返回张量列表。

disable_grouping (`bool`, *kwargs*, *可选*) : 是否禁用按尺寸对图像进行分组，从而逐个处理图像而非批量处理。如果为 None，则当图像位于 CPU 上时设置为 True，否则设置为 False。此选择基于经验观察，详见此处：https://github.com/huggingface/transformers/pull/38157

image_seq_length (`int`, *kwargs*, *可选*) : 输入中每张图片所使用的图像 token 数量。为向后兼容而添加，但在未来的模型中，应将其设置为处理器的属性。

patch_size (`int`, *kwargs*, *可选*，默认为 `self.patch_size`)：单个 patch token 的边长（以像素为单位）。图像会被填充为该值的整数倍。

max_side (`int`, *kwargs*, *可选*) : 最长边像素上限。未设置表示不进行最长边缩放。

构建一个 NeoMMEImageProcessor 图像处理器。

#### preprocess[[transformers.NeoMMEImageProcessor.preprocess]]

```python
preprocess(images: typing.Union[ForwardRef('PIL.Image.Image'), numpy.ndarray, ForwardRef('torch.Tensor'), list['PIL.Image.Image'], list[numpy.ndarray], list['torch.Tensor']], **kwargs: *<class 'transformers.models.neomme.image_processing_neomme.NeoMMEImageProcessorKwargs'>)
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/neomme/image_processing_neomme.py#L136)

**参数：**

images (`Union[PIL.Image.Image, numpy.ndarray, torch.Tensor, list[PIL.Image.Image], list[numpy.ndarray], list[torch.Tensor]]`) : 要预处理的图像。期望输入单张或一批像素值在 0 到 255 之间的图像。如果传入的图像像素值在 0 到 1 之间，请设置 `do_rescale=False`。

do_convert_rgb (`bool`, *kwargs*, *可选*) : 是否将图像转换为 RGB。

do_resize (`bool`，*kwargs*，*可选*)：是否调整图像大小。

size (`Annotated[int | list[int] | tuple[int, ...] | dict[str, int] | None, None]`, *kwargs*)：描述模型的最大输入维度。

default_to_square (`bool`, *kwargs*, *可选*) : 当 size 为 int 时，是否在调整大小时默认使用正方形图像。

crop_size (`Annotated[int | list[int] | tuple[int, ...] | dict[str, int] | None, None]`, *kwargs*) : 应用 `center_crop` 后输出图像的尺寸。

resample (`Annotated[Union[int, PILImageResampling, NoneType], None]`, *kwargs*) : 如果调整图像大小，则使用的重采样滤波器。它可以是枚举 `PILImageResampling` 中的一个值。仅当 `do_resize` 设置为 `True` 时才会生效。

do_rescale (`bool`, *kwargs*, *可选*) : 是否对图像进行重新缩放。

rescale_factor (`float`, *kwargs*, *可选*) : 当 `do_rescale` 设置为 `True` 时，用于对图像进行缩放的缩放因子。

do_normalize (`bool`, *kwargs*, *可选*) : 是否对图像进行归一化。

image_mean (`Union[float, list[float], tuple[float, ...]]`，*kwargs*，*可选*)：用于归一化的图像均值。仅当 `do_normalize` 设置为 `True` 时生效。

image_std (`Union[float, list[float], tuple[float, ...]]`, *kwargs*, *可选*) : 用于归一化的图像标准差。仅当 `do_normalize` 设置为 `True` 时生效。

do_pad (`bool`, *kwargs*, *可选*) : 是否对图像进行填充。填充操作会将图像填充至批次中的最大尺寸，或填充至每张图像的固定正方形尺寸。具体的填充策略取决于模型。

pad_size (`Annotated[int | list[int] | tuple[int, ...] | dict[str, int] | None, None]`, *kwargs*) : 用于将图像填充到的尺寸，格式为 `{"height": int, "width" int}`。该尺寸必须大于预处理中提供的任何图像尺寸。如果未提供 `pad_size`，图像将被填充到批次中最大的高度和宽度。仅在 `do_pad=True.` 时应用。

do_center_crop (`bool`, *kwargs*, *可选*) : 是否对图像进行居中裁剪。

data_format (`Union[str, ~image_utils.ChannelDimension]`，*kwargs*，*可选*)：仅支持 `ChannelDimension.FIRST`。为兼容旧版处理器而添加。

input_data_format (`Union[str, ~image_utils.ChannelDimension]`, *kwargs*, *可选*) : 输入图像的通道维度格式。如果未设置，则从输入图像中推断通道维度格式。可以是以下之一： - `"channels_first"` 或 `ChannelDimension.FIRST`：图像为 (num_channels, height, width) 格式。 - `"channels_last"` 或 `ChannelDimension.LAST`：图像为 (height, width, num_channels) 格式。 - `"none"` 或 `ChannelDimension.NONE`：图像为 (height, width) 格式。

device (`Annotated[Union[str, torch.device, NoneType], None]`, *kwargs*)：用于处理视频的设备。如果未设置，则从输入视频中推断设备。

return_tensors (`Annotated[str | ~utils.generic.TensorType | None, None]`, *kwargs*) : 如果设置为 `'pt'`，则返回堆叠的张量，否则返回张量列表。

disable_grouping (`bool`, *kwargs*, *可选*) : 是否禁用按尺寸对图像进行分组，从而逐个处理图像而非批量处理。如果为 None，则当图像位于 CPU 上时设置为 True，否则设置为 False。此选择基于经验观察，详见此处：https://github.com/huggingface/transformers/pull/38157

image_seq_length (`int`, *kwargs*, *可选*) : 输入中每张图片所使用的图像 token 数量。为向后兼容而添加，但在未来的模型中，应将其设置为处理器的属性。

patch_size (`int`, *kwargs*, *可选*，默认为 `self.patch_size`)：单个 patch token 的边长（以像素为单位）。图像会被填充为该值的整数倍。

max_side (`int`, *kwargs*, *可选*) : 最长边像素上限。未设置表示不进行最长边缩放。

**返回值：**

形状为 `(total_patches, 3 * patch_size ** 2)` 的 `pixel_values` 和形状为 `(batch_size, 2)` 的 `image_grid_hw` 组成的 [BatchFeature](/docs/transformers/main/zh/main_classes/feature_extractor#transformers.BatchFeature)。`pixel_values` 拼接了批次中每张图片的 patch。

## NeoMMEProcessor[[transformers.NeoMMEProcessor]]

#### transformers.NeoMMEProcessor[[transformers.NeoMMEProcessor]]

```python
transformers.NeoMMEProcessor(image_processor = None, tokenizer = None, chat_template = None, **kwargs)
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/neomme/processing_neomme.py#L32)

**参数：**

image_processor (`NeoMMEImageProcessor`)：图像处理器是必需的输入。

tokenizer (`tokenizer_class`)：分词器是必需的输入。

chat_template (`str`) : 一个 Jinja 模板，用于将聊天中的消息列表转换为可分词的字符串。

构建一个 NeoMMEProcessor，它将图像处理器和分词器封装为单个处理器。

[NeoMMEProcessor](/docs/transformers/main/zh/model_doc/neomme#transformers.NeoMMEProcessor) 提供了 [NeoMMEImageProcessor](/docs/transformers/main/zh/model_doc/neomme#transformers.NeoMMEImageProcessor) 和 `tokenizer_class` 的所有功能。有关更多信息，请参阅 [~NeoMMEImageProcessor](/docs/transformers/main/zh/model_doc/neomme#transformers.NeoMMEImageProcessor) 和 `~tokenizer_class`。

#### __调用__[[transformers.NeoMMEProcessor.__call__]]

```python
__call__(images: ImageInput | None = None, text: TextInput | list[TextInput] | None = None, **kwargs: Unpack[ProcessingKwargs])
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/neomme/processing_neomme.py#L53)

**参数：**

images (`ImageInput`，*可选*)：要预处理的图像。期望输入单张图像或一批图像，其像素值范围为 0 到 255。如果传入的图像像素值在 0 到 1 之间，请设置 `do_rescale=False`。

text (`TextInput | list[TextInput]`, *可选*) : 要编码的序列或序列批次。每个序列可以是字符串或字符串列表（预分词字符串）。如果传入预分词输入，请设置 `is_split_into_words=True` 以避免与批量输入产生歧义。

return_tensors (`str` 或 [TensorType](/docs/transformers/main/zh/internal/file_utils#transformers.TensorType)，*可选*)：如果设置，将返回特定框架的张量。可接受的值为： - `'pt'`：返回 PyTorch `torch.Tensor` 对象。 - `'np'`：返回 NumPy `np.ndarray` 对象。

**返回值：**

包含 `input_ids` 和 `attention_mask` 的 [BatchFeature](/docs/transformers/main/zh/main_classes/feature_extractor#transformers.BatchFeature)。图像输入还会返回 `position_ids` 和 `pixel_values`。

#### apply_chat_template[[transformers.NeoMMEProcessor.apply_chat_template]]

```python
apply_chat_template(conversation: list[dict[str, str]] | list[list[dict[str, str]]], chat_template: str | None = None, task: Literal['query', 'document'] | None = None, processor_kwargs: dict | None = None, **kwargs)
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/neomme/processing_neomme.py#L136)

应用已配置的检索模板，并可选择对其输出进行分词。

当 `tokenize=True` 时，图像内容必须包含图像、URL、路径或 base64 值。通过 `processor_kwargs` 传递 `max_length` 或 `max_side` 等处理选项。

## NeoMMEModel[[transformers.NeoMMEModel]]

#### transformers.NeoMMEModel[[transformers.NeoMMEModel]]

```python
transformers.NeoMMEModel(config: NeoMMEConfig)
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/neomme/modeling_neomme.py#L492)

**参数：**

config ([NeoMMEConfig](/docs/transformers/main/zh/model_doc/neomme#transformers.NeoMMEConfig))：模型配置类，包含模型的所有参数。通过配置文件进行初始化时，不会加载与模型关联的权重，仅加载配置。请查看 [from_pretrained()](/docs/transformers/main/zh/main_classes/model#transformers.PreTrainedModel.from_pretrained) 方法以加载模型权重。

裸的 NeoMME 模型。它使用一个双向 Transformer 编码器来编码文本 token 和图像 patch。

该模型继承自 [PreTrainedModel](/docs/transformers/main/zh/main_classes/model#transformers.PreTrainedModel)。请查阅父类文档，了解该库为所有模型实现的通用方法（例如下载或保存、调整输入嵌入大小、剪枝头等）。

该模型也是 PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) 的子类。请将其作为常规的 PyTorch Module 使用，有关通用用法和行为的所有事项，请参阅 PyTorch 文档。

#### forward[[transformers.NeoMMEModel.forward]]

```python
forward(input_ids: LongTensor, attention_mask: typing.Optional[torch.Tensor] = None, position_ids: typing.Optional[torch.LongTensor] = None, pixel_values: typing.Optional[torch.Tensor] = None, **kwargs: *<class 'transformers.utils.generic.TransformersKwargs'>)
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/neomme/modeling_neomme.py#L535)

**参数：**

input_ids (`torch.LongTensor`，形状为 `(batch_size, sequence_length)`)：输入序列词元在词汇表中的索引。默认情况下，填充部分将被忽略。可以使用 [AutoTokenizer](/docs/transformers/main/zh/model_doc/auto#transformers.AutoTokenizer) 获取索引。有关详细信息，请参阅 [PreTrainedTokenizer.encode()](/docs/transformers/main/zh/internal/tokenization_utils#transformers.PreTrainedTokenizerBase.encode) 和 [PreTrainedTokenizer.__call__()](/docs/transformers/main/zh/internal/tokenization_utils#transformers.PreTrainedTokenizerBase.__call__)。[什么是输入 ID？](../glossary#input-ids)

attention_mask (`torch.Tensor`，形状为 `(batch_size, sequence_length)`，*可选*)：用于避免对填充（padding）标记索引执行注意力机制的掩码。掩码值取自 `[0, 1]`： - 1 表示**未掩码**的标记， - 0 表示**已掩码**的标记。 [什么是注意力掩码？](../glossary#attention-mask)

position_ids (`torch.LongTensor`，形状为 `(2, batch_size, sequence_length)` 或 `(batch_size, sequence_length)`，*可选*)：输入标记的位置。[NeoMMEProcessor](/docs/transformers/main/zh/model_doc/neomme#transformers.NeoMMEProcessor) 为文档图像返回双轴位置。文本输入使用单轴位置张量。

pixel_values (`torch.Tensor`，形状为 `(num_patches, 3 * patch_size ** 2)`，*可选*)：由 [NeoMMEProcessor](/docs/transformers/main/zh/model_doc/neomme#transformers.NeoMMEProcessor) 返回的展平图像块。模型会将这些图像块放置在 `input_ids` 中的图像占位符处。

**返回：** [BaseModelOutput](/docs/transformers/main/zh/main_classes/output#transformers.modeling_outputs.BaseModelOutput) 或 `tuple(torch.Tensor)`

一个 [BaseModelOutput](/docs/transformers/main/zh/main_classes/output#transformers.modeling_outputs.BaseModelOutput) 或 `torch.Tensor` 元组（如果传入了 `return_dict=False` 或 `config.return_dict=False`），其包含的元素取决于配置（[NeoMMEConfig](/docs/transformers/main/zh/model_doc/neomme#transformers.NeoMMEConfig)）和输入。

[NeoMMEModel](/docs/transformers/main/zh/model_doc/neomme#transformers.NeoMMEModel) 的 forward 方法重写了 `__call__` 特殊方法。

尽管前向传播的实现需要在此函数中定义，但之后应调用 `Module` 实例，而不是直接调用此函数，因为前者会负责执行预处理和后处理步骤，而后者会静默地忽略这些步骤。

- **last_hidden_state**（形状为 `(batch_size, sequence_length, hidden_size)` 的 `torch.Tensor`）-- 模型最后一层输出的隐藏状态序列。
- **hidden_states** (`tuple(torch.Tensor)`，*可选*，在传入 `output_hidden_states=True` 或 `config.output_hidden_states=True` 时返回) -- 一个 `torch.Tensor` 元组（如果模型具有嵌入层，则包含嵌入层的输出，以及每一层的输出），形状为 `(batch_size, sequence_length, hidden_size)`。

  模型在每一层输出处的隐藏状态，以及可选的初始嵌入输出。
- **attentions** (`tuple(torch.Tensor)`，*可选*，当传入 `output_attentions=True` 或 `config.output_attentions=True` 时返回) -- 一个 `torch.Tensor` 元组（每层一个），形状为 `(batch_size, num_heads, sequence_length, sequence_length)`。

  经过注意力 softmax 后的注意力权重，用于在自注意力头中计算加权平均值。

## NeoMMEForMaskedLM[[transformers.NeoMMEForMaskedLM]]

#### transformers.NeoMMEForMaskedLM[[transformers.NeoMMEForMaskedLM]]

```python
transformers.NeoMMEForMaskedLM(config: NeoMMEConfig)
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/neomme/modeling_neomme.py#L612)

**参数：**

config ([NeoMMEConfig](/docs/transformers/main/zh/model_doc/neomme#transformers.NeoMMEConfig))：模型配置类，包含模型的所有参数。通过配置文件进行初始化时，不会加载与模型关联的权重，仅加载配置。请查看 [from_pretrained()](/docs/transformers/main/zh/main_classes/model#transformers.PreTrainedModel.from_pretrained) 方法以加载模型权重。

采用分解式掩码标记解码器的 NeoMME 模型。

该模型继承自 [PreTrainedModel](/docs/transformers/main/zh/main_classes/model#transformers.PreTrainedModel)。请查阅父类文档，了解该库为所有模型实现的通用方法（例如下载或保存、调整输入嵌入大小、剪枝头等）。

该模型也是 PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) 的子类。请将其作为常规的 PyTorch Module 使用，有关通用用法和行为的所有事项，请参阅 PyTorch 文档。

#### forward[[transformers.NeoMMEForMaskedLM.forward]]

```python
forward(input_ids: typing.Optional[torch.LongTensor] = None, attention_mask: typing.Optional[torch.Tensor] = None, position_ids: typing.Optional[torch.LongTensor] = None, pixel_values: typing.Optional[torch.Tensor] = None, labels: typing.Optional[torch.LongTensor] = None, **kwargs: *<class 'transformers.utils.generic.TransformersKwargs'>)
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/neomme/modeling_neomme.py#L626)

**参数：**

input_ids (`torch.LongTensor`，形状为 `(batch_size, sequence_length)`，*可选*)：输入序列中 token 在词汇表中的索引。默认情况下，填充（padding）将被忽略。可以使用 [AutoTokenizer](/docs/transformers/main/zh/model_doc/auto#transformers.AutoTokenizer) 获取索引。有关详细信息，请参阅 [PreTrainedTokenizer.encode()](/docs/transformers/main/zh/internal/tokenization_utils#transformers.PreTrainedTokenizerBase.encode) 和 [PreTrainedTokenizer.__call__()](/docs/transformers/main/zh/internal/tokenization_utils#transformers.PreTrainedTokenizerBase.__call__)。[什么是输入 ID？](../glossary#input-ids)

attention_mask (`torch.Tensor`，形状为 `(batch_size, sequence_length)`，*可选*)：用于避免对填充（padding）标记索引执行注意力机制的掩码。掩码值取自 `[0, 1]`： - 1 表示**未掩码**的标记， - 0 表示**已掩码**的标记。 [什么是注意力掩码？](../glossary#attention-mask)

position_ids (`torch.LongTensor`，形状为 `(batch_size, sequence_length)`，*可选*)：输入序列中每个 token 在位置嵌入中的位置索引。取值范围为 `[0, config.n_positions - 1]`。[什么是位置 ID？](../glossary#position-ids)

pixel_values (`torch.Tensor`，形状为 `(batch_size, num_channels, image_size, image_size)`，*可选*)：与输入图像对应的张量。可以使用 [NeoMMEImageProcessor](/docs/transformers/main/zh/model_doc/neomme#transformers.NeoMMEImageProcessor) 获取像素值。有关详细信息，请参阅 [NeoMMEImageProcessor.__call__()](/docs/transformers/main/zh/model_doc/molmo2#transformers.Molmo2ImageProcessor.__call__)（[NeoMMEProcessor](/docs/transformers/main/zh/model_doc/neomme#transformers.NeoMMEProcessor) 使用 [NeoMMEImageProcessor](/docs/transformers/main/zh/model_doc/neomme#transformers.NeoMMEImageProcessor) 处理图像）。

labels (`torch.LongTensor`，形状为 `(batch_size, sequence_length)`，*可选*)：用于掩码语言建模损失的标签。索引应在 `[0, ..., config.vocab_size - 1]` 或 `-100` 范围内；只有标签不同于 `-100` 的 token 才会参与计算。

**返回：** [MaskedLMOutput](/docs/transformers/main/zh/main_classes/output#transformers.modeling_outputs.MaskedLMOutput) 或 `tuple(torch.Tensor)`

一个 [MaskedLMOutput](/docs/transformers/main/zh/main_classes/output#transformers.modeling_outputs.MaskedLMOutput) 或 `torch.Tensor` 元组（如果传入了 `return_dict=False` 或 `config.return_dict=False`），其包含的元素取决于配置（[NeoMMEConfig](/docs/transformers/main/zh/model_doc/neomme#transformers.NeoMMEConfig)）和输入。

[NeoMMEForMaskedLM](/docs/transformers/main/zh/model_doc/neomme#transformers.NeoMMEForMaskedLM) 的 forward 方法重写了 `__call__` 特殊方法。

尽管前向传播的实现需要在此函数中定义，但之后应调用 `Module` 实例，而不是直接调用此函数，因为前者会负责执行预处理和后处理步骤，而后者会静默地忽略这些步骤。

- **loss** (`torch.Tensor`，形状为 `(1,)`，*可选*，当提供 `labels` 时返回) -- 掩码语言建模（MLM）损失。
- **logits**（形状为 `(batch_size, sequence_length, config.vocab_size)` 的 `torch.Tensor`）-- 语言建模头的预测分数（SoftMax 之前每个词汇表 token 的分数）。
- **hidden_states** (`tuple(torch.Tensor)`，*可选*，在传入 `output_hidden_states=True` 或 `config.output_hidden_states=True` 时返回) -- 一个 `torch.Tensor` 元组（如果模型具有嵌入层，则包含嵌入层的输出，以及每一层的输出），形状为 `(batch_size, sequence_length, hidden_size)`。

  模型在每一层输出处的隐藏状态，以及可选的初始嵌入输出。
- **attentions** (`tuple(torch.Tensor)`，*可选*，当传入 `output_attentions=True` 或 `config.output_attentions=True` 时返回) -- 一个 `torch.Tensor` 元组（每层一个），形状为 `(batch_size, num_heads, sequence_length, sequence_length)`。

  经过注意力 softmax 后的注意力权重，用于在自注意力头中计算加权平均值。

示例：

```python
>>> from transformers import AutoTokenizer, NeoMMEForMaskedLM
>>> import torch

>>> tokenizer = AutoTokenizer.from_pretrained("Hcompany/NeoMME-260M")
>>> model = NeoMMEForMaskedLM.from_pretrained("Hcompany/NeoMME-260M")

>>> inputs = tokenizer("The capital of France is <mask>.", return_tensors="pt")

>>> with torch.no_grad():
...     logits = model(**inputs).logits

>>> # retrieve index of <mask>
>>> mask_token_index = (inputs.input_ids == tokenizer.mask_token_id)[0].nonzero(as_tuple=True)[0]

>>> predicted_token_id = logits[0, mask_token_index].argmax(axis=-1)
>>> tokenizer.decode(predicted_token_id)
...

>>> labels = tokenizer("The capital of France is Paris.", return_tensors="pt")["input_ids"]
>>> # mask labels of non-<mask> tokens
>>> labels = torch.where(inputs.input_ids == tokenizer.mask_token_id, labels, -100)

>>> outputs = model(**inputs, labels=labels)
>>> round(outputs.loss.item(), 2)
...
```

## NeoMMEForRetrieval[[transformers.NeoMMEForRetrieval]]

#### transformers.NeoMMEForRetrieval[[transformers.NeoMMEForRetrieval]]

```python
transformers.NeoMMEForRetrieval(config: NeoMMEConfig)
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/neomme/modeling_neomme.py#L719)

**参数：**

config ([NeoMMEConfig](/docs/transformers/main/zh/model_doc/neomme#transformers.NeoMMEConfig))：模型配置类，包含模型的所有参数。通过配置文件进行初始化时，不会加载与模型关联的权重，仅加载配置。请查看 [from_pretrained()](/docs/transformers/main/zh/main_classes/model#transformers.PreTrainedModel.from_pretrained) 方法以加载模型权重。

带有多向量和稠密检索头的 NeoMME 模型。一次前向传播即可返回用于 MaxSim 评分的 token 嵌入以及用于余弦相似度的均值池化嵌入。

该模型继承自 [PreTrainedModel](/docs/transformers/main/zh/main_classes/model#transformers.PreTrainedModel)。请查阅父类文档，了解该库为所有模型实现的通用方法（例如下载或保存、调整输入嵌入大小、剪枝头等）。

该模型也是 PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) 的子类。请将其作为常规的 PyTorch Module 使用，有关通用用法和行为的所有事项，请参阅 PyTorch 文档。

#### forward[[transformers.NeoMMEForRetrieval.forward]]

```python
forward(input_ids: typing.Optional[torch.LongTensor] = None, attention_mask: typing.Optional[torch.Tensor] = None, position_ids: typing.Optional[torch.LongTensor] = None, pixel_values: typing.Optional[torch.Tensor] = None, output_multivector: bool = True, output_dense: bool = True, dense_dim: int | None = None, **kwargs: *<class 'transformers.utils.generic.TransformersKwargs'>)
```

[来源](https://github.com/huggingface/transformers/blob/main/src/transformers/models/neomme/modeling_neomme.py#L727)

**参数：**

input_ids (`torch.LongTensor`，形状为 `(batch_size, sequence_length)`，*可选*)：输入序列中 token 在词汇表中的索引。默认情况下，填充（padding）将被忽略。可以使用 [AutoTokenizer](/docs/transformers/main/zh/model_doc/auto#transformers.AutoTokenizer) 获取索引。有关详细信息，请参阅 [PreTrainedTokenizer.encode()](/docs/transformers/main/zh/internal/tokenization_utils#transformers.PreTrainedTokenizerBase.encode) 和 [PreTrainedTokenizer.__call__()](/docs/transformers/main/zh/internal/tokenization_utils#transformers.PreTrainedTokenizerBase.__call__)。[什么是输入 ID？](../glossary#input-ids)

attention_mask (`torch.Tensor`，形状为 `(batch_size, sequence_length)`，*可选*)：用于避免对填充（padding）标记索引执行注意力机制的掩码。掩码值取自 `[0, 1]`： - 1 表示**未掩码**的标记， - 0 表示**已掩码**的标记。 [什么是注意力掩码？](../glossary#attention-mask)

position_ids (`torch.LongTensor`，形状为 `(batch_size, sequence_length)`，*可选*)：输入序列中每个 token 在位置嵌入中的位置索引。取值范围为 `[0, config.n_positions - 1]`。[什么是位置 ID？](../glossary#position-ids)

pixel_values (`torch.Tensor`，形状为 `(batch_size, num_channels, image_size, image_size)`，*可选*)：与输入图像对应的张量。可以使用 [NeoMMEImageProcessor](/docs/transformers/main/zh/model_doc/neomme#transformers.NeoMMEImageProcessor) 获取像素值。有关详细信息，请参阅 [NeoMMEImageProcessor.__call__()](/docs/transformers/main/zh/model_doc/molmo2#transformers.Molmo2ImageProcessor.__call__)（[NeoMMEProcessor](/docs/transformers/main/zh/model_doc/neomme#transformers.NeoMMEProcessor) 使用 [NeoMMEImageProcessor](/docs/transformers/main/zh/model_doc/neomme#transformers.NeoMMEImageProcessor) 处理图像）。

output_multivector (`bool`, *可选*, 默认为 `True`) : 是否返回用于延迟交互检索的 token 嵌入。

output_dense (`bool`，*可选*，默认为 `True`)：是否返回每个输入的一个均值池化稠密嵌入。

dense_dim (`int`, *optional*) : 用于返回稠密嵌入的 Matryoshka 前缀的宽度。模型会在归一化之前截断池化向量。

**返回：** `NeoMMEForRetrievalOutput` 或 `tuple(torch.Tensor)`

`NeoMMEForRetrievalOutput` 或 `torch.Tensor` 元组（如果传入 `return_dict=False` 或 `config.return_dict=False`），其包含的元素取决于配置（[NeoMMEConfig](/docs/transformers/main/zh/model_doc/neomme#transformers.NeoMMEConfig)）和输入。

[NeoMMEForRetrieval](/docs/transformers/main/zh/model_doc/neomme#transformers.NeoMMEForRetrieval) 的 forward 方法重写了 `__call__` 特殊方法。

尽管前向传播的实现需要在此函数中定义，但之后应调用 `Module` 实例，而不是直接调用此函数，因为前者会负责执行预处理和后处理步骤，而后者会静默地忽略这些步骤。

- **last_hidden_state**（形状为 `(batch_size, sequence_length, hidden_size)` 的 `torch.Tensor`）-- 模型最后一层输出的隐藏状态序列。
- **hidden_states** (`tuple(torch.Tensor)`，*可选*，在传入 `output_hidden_states=True` 或 `config.output_hidden_states=True` 时返回) -- 一个 `torch.Tensor` 元组（如果模型具有嵌入层，则包含嵌入层的输出，以及每一层的输出），形状为 `(batch_size, sequence_length, hidden_size)`。

  模型在每一层输出处的隐藏状态，以及可选的初始嵌入输出。
- **attentions** (`tuple(torch.Tensor)`，*可选*，当传入 `output_attentions=True` 或 `config.output_attentions=True` 时返回) -- 一个 `torch.Tensor` 元组（每层一个），形状为 `(batch_size, num_heads, sequence_length, sequence_length)`。

  经过注意力 softmax 后的注意力权重，用于在自注意力头中计算加权平均值。
- **loss** (`torch.Tensor`，形状为 `(1,)`，*可选*) -- 检索损失。该值始终为 `None`。
- **embeddings**（形状为 `(batch_size, sequence_length, embedding_dim)` 的 `torch.Tensor`，*可选*）-- 用于延迟交互检索的归一化 token 嵌入。填充行已置零。请使用 MeanMaxSim 对其进行评分。
- **dense_embeddings** (`torch.Tensor`，形状为 `(batch_size, hidden_size)` 或 `(batch_size, dense_dim)`，*可选*) -- 每个输入对应的归一化均值池化嵌入。当设置了 `dense_dim` 时，最后一维为 `dense_dim`。使用余弦相似度对其进行评分。

## 引用

```bibtex
@misc{lac2026neommesingletowermultimodalnativemultilingual,
      title={NeoMME: A Single-Tower Multimodal-Native Multilingual Foundation Encoder for Efficient Fine-Tuning and Inference},
      author={Aurélien Lac and Tony Wu},
      year={2026},
      eprint={2609.01657},
      archivePrefix={arXiv},
      primaryClass={cs.IR},
      url={https://arxiv.org/abs/2609.01657},
}
```

