Atomic Proposition Embeddings (APE)

immagine

Conference License: CC BY-SA 4.0 GitHub

APE is a language representation model that maps sentences to variable-size sets of independent atomic-proposition embeddings. It consists of a decoder with learned query vectors built on top of an encoder backbone. The query vectors attend to the encoder's hidden states via cross-attention. Each of the resulting vectors is passed through (1) an embedding head, to project it into the teacher sentence embedding space; (2) an activity head, to check whether the resulting vector represents an actual propositon or should be discarded.

immagine

This model has been trained on sentences with a maximum number of five atomic propositions each.

Usage

This model relies on the APE package. Install it by running:

# pip
pip install "git+https://github.com/SapienzaNLP/APE.git"

# or uv (inside a uv project)
uv add "git+https://github.com/SapienzaNLP/APE.git"

Load a Pretrained APE Model

You can load the pretrained model's weights from this HF repository with APE.from_pretrained:

from ape import APE, APEScore

model = APE.from_pretrained("sapienzanlp/ape-bge-small")

sentences = [
    "Rome was built in 753 BC and is now the capital of Italy.",
    "Rome is the capital of Italy.",
]

prop_embds, act_scores = model.encode(
    sentences,
    activity_threshold=0.6,
    return_scores=True
)

print([e.shape for e in prop_embds])
# [torch.Size([2, 384]), torch.Size([1, 384])]

print("activity scores:", [[round(x, 4) for x in s.tolist()] for s in act_scores])
# activity scores: [[0.9988, 0.9984], [0.9987]]

print("all slot activities:")
for s, row in zip("AB", model.activity_scores(sentences)):
    print(s, [round(float(x), 3) for x in row])
# all slot activities:
# A [0.001, 0.0, 0.999, 0.0, 0.001, 0.998, 0.0, 0.0] -> one active slot
# B [0.0,   0.0, 0.999, 0.0, 0.001, 0.001, 0.0, 0.0] -> two active slots

An output vector counts as a proposition embedding if its activity score exceeds activity_threshold (we recommend ~0.6 as a starting point). Every sentence gets at least one active embedding.

Inference Scoring Rules

With APE, sentence-to-sentence comparisons produce cosine similarity matrices. We can extract a single score from them, with the aggregation technique (scoring rule) depdending on the task.

Rule Description Task
hungarian Optimal one-to-one matching between Sentence A and Sentence B, averaged over matched pairs. Symmetric scoring rule (sentence ordering is irrelevant). Propositional equivalence (e.g., PAWS-style).
maxsim Mean of each proposition's best match, averaged over both directions. Symmetric scoring rule (sentence ordering is irrelevant). General semantic similarity.
pool Cosine similarity of the mean-pooled proposition embedding sets. Symmetric scoring rule (sentence ordering is irrelevant). General semantic similarity. Tends to work worse than maxsim.
h_min_to_p Worst best-match of any Sentence A-proposition (hypothesis/query) to Sentence B propositions (premise/document). Asymmetric scoring rule (pass hypothesis/query first, then premise/document) NLI entailment detection; Proposition-level retrieval.¹

¹Note: APE has not yet been trained on query/passage pairs, so typical asymmetric retrieval may not work as intended.

You can access these scoring rules from the APEScore class:

scorer = APEScore(prop_embds[1], prop_embds[0])  # (hypothesis, premise)

print("Hungarian Score: ", round(scorer.score("hungarian"), 3))
print("MaxSim Score:    ", round(scorer.score("maxsim"), 3))
print("Pooled Score:    ", round(scorer.score("pool"), 3))
print("H2P Score:       ", round(scorer.score("h_min_to_p"), 3))

# Hungarian Score: 0.973
# MaxSim Score:    0.939
# Pooled Score:    0.973
# H2P Score:       0.937

# to pretty-print the full cosine similarity matrix
scorer.print_similarity_matrix()
#         B0     B1
# A0   0.838  0.973

Interpretability via Proposition Seeding

APE proposition embeddings are not tied to any text, but they can be interpreted via proposition seeding. We encode a candidate atomic proposition (the seed) with APE anche check which of the sentence's proposition embeddings is the strongest match.

import torch
from ape import APE, APEScore

model = APE.from_pretrained("sapienzanlp/ape-bge-small")

sentence = "Rome was built in 753 BC and is now the capital of Italy."
prop_seeds = [
    "Rome was built in 753 BC.",
    "Rome is now the capital of Italy.",
]

prop_embds = model.encode(sentence)                # [n_propositions, D]
seed_embds = torch.cat(model.encode(prop_seeds))   # one embedding per seed

scorer = APEScore(seed_embds, prop_embds)  # rows: seeds, columns: APE propositions
scorer.print_similarity_matrix()

for seed, j in zip(prop_seeds, scorer.similarity_matrix().argmax(axis=1)):
    print(f"{seed!r} -> proposition B{j}")

This will output:

        B0     B1
A0   0.996  0.862
A1   0.833  0.985

'Rome was built in 753 BC.' -> proposition B0
'Rome is now the capital of Italy.' -> proposition B1

Seeds should be single atomic propositions, so that APE encodes each one into exactly one embedding. A seed that contains several propositions produces several rows in seed_embds. If APE mistakenly produces more than one vector for a single atomic proposition, one way around it is to pool the embeddings of the seed before matching.

Performance

Zero-shot performance measured by "AUC | Average Precision" for PAWS-Wiki and SNLI (entailment vs rest), Spearman correlation coefficient for STS-B and SICK-R, and MRR for PropSearch.

Note that APE is designed to represent propositions as independent and self-contained; therefore, the slight performance decrease on STS benchmarks is likely due to the discarded inter-propositional relationships.

Model Size PAWS-Wiki SNLI STS-B SICK-R PropSearch²
ape-bge-small 40M 81.1 | 77.1 84.1 | 72.3 84.9 78.8 91.4
SSE-T5 (multi-vector) 879M 76.0 | 73.4 80.7 | 69.1 80.1 76.1 55.4
bge-small-en-v1.5 33M 60.5 | 56.0 81.1 | 65.3 86.8 79.9 83.4
bge-large-en-v1.5 335M 64.2 | 60.6 82.0 | 66.6 87.5 81.7 86.2
embeddinggemma-300m 308M 66.1 | 62.9 84.2 | 68.5 88.8 82.1 90.9
Qwen3-Embedding-0.6B 596M 74.0 | 67.0 81.2 | 65.3 91.2 84.9 85.1

²For PropSearch, we show results (MRR) for the most challenging sub-task (6 or more propositions in the correct source sentence).

We use the hungarian scoring rule for PAWS-Wiki, h_min_to_p for SNLI and PropSearch, and maxsim for STS-B and SICK-R.

Citation

If you find our work helpful, please consider citing it:

@inproceedings{ortame-navigli-2026-variable,
    title = "Variable-size Discovery and Representation of Atomic Propositions",
    author = "Ortame, Francesco  and
      Navigli, Roberto",
    editor = "Lee, Hung-Yi  and
      Dev, Sunipa  and
      Li, Jessy  and
      Elliott, Desmond",
    booktitle = "Proceedings of the 2026 Conference on Empirical Methods in Natural Language Processing",
    month = oct,
    year = "2026",
    address = "Budapest, Hungary",
    publisher = "Association for Computational Linguistics",
    url = "https://aclanthology.org/2026.emnlp-main.2302/",
    pages = "52330--52348",
    ISBN = "979-8-89176-459-0"
}
Downloads last month
-
Safetensors
Model size
40.6M params
Tensor type
F32
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for sapienzanlp/ape-bge-small

Finetuned
(552)
this model

Space using sapienzanlp/ape-bge-small 1

Collection including sapienzanlp/ape-bge-small