Skip to content

Commit 975d530

Browse files
authored
Merge pull request #771 from superlinked/fix/bge-flash-default-fp16
fix(server): align BGE Flash profiles with FP16 default
2 parents 2e6350e + 6d17e6f commit 975d530

4 files changed

Lines changed: 88 additions & 9 deletions

File tree

‎packages/sie_server/models/BAAI__bge-m3.yaml‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ max_sequence_length: 8192
2020
profiles:
2121
default:
2222
max_batch_tokens: 16384
23-
compute_precision: bfloat16
23+
compute_precision: float16
2424
adapter_path: sie_server.adapters.bge_m3_flash:BGEM3FlashAdapter
2525
adapter_options:
2626
loadtime: {}
@@ -53,13 +53,15 @@ profiles:
5353
- multivector
5454
candle:
5555
extends: default
56+
compute_precision: bfloat16
5657
adapter_path: sie_server_rust.adapters.candle:CandleEmbeddingAdapter
5758
adapter_options:
5859
runtime:
5960
pooling: cls
6061
normalize: true
6162
banking:
6263
extends: default
64+
compute_precision: bfloat16
6365
adapter_options:
6466
runtime:
6567
pooling: cls
@@ -68,6 +70,7 @@ profiles:
6870
instruction: Classify banking intent
6971
medical-vn:
7072
extends: default
73+
compute_precision: bfloat16
7174
adapter_options:
7275
runtime:
7376
pooling: cls

‎packages/sie_server/tests/adapters/test_bge_m3_flash.py‎

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@
77
import numpy as np
88
import pytest
99
import torch
10+
import transformers
1011
import yaml
12+
from sie_server.adapters._types import ComputePrecision
1113
from sie_server.adapters.bge_m3_flash import BGEM3FlashAdapter
1214
from sie_server.config.model import ModelConfig
1315
from sie_server.core.inference_output import EncodeOutput, SparseVector
16+
from sie_server.core.loader import _build_adapter_kwargs
1417
from sie_server.types.inputs import Item
1518
from transformers import XLMRobertaConfig
1619
from transformers.models.xlm_roberta.modeling_xlm_roberta import XLMRobertaEmbeddings
@@ -93,6 +96,68 @@ def test_score_task_enabled(self, config: ModelConfig) -> None:
9396
def test_score_in_outputs(self, config: ModelConfig) -> None:
9497
assert "score" in config.outputs
9598

99+
def test_resolved_profile_precisions(self, config: ModelConfig) -> None:
100+
assert {name: config.resolve_profile(name).compute_precision for name in config.profiles} == {
101+
"default": "float16",
102+
"dense": "float16",
103+
"sparse": "float16",
104+
"multivector": "float16",
105+
"candle": "bfloat16",
106+
"banking": "bfloat16",
107+
"medical-vn": "bfloat16",
108+
"bge_m3_flag": None,
109+
}
110+
111+
def test_default_precision_reaches_adapter_loading(
112+
self,
113+
config: ModelConfig,
114+
monkeypatch: pytest.MonkeyPatch,
115+
) -> None:
116+
kwargs = _build_adapter_kwargs(config, "bfloat16")
117+
assert kwargs["compute_precision"] == "float16"
118+
assert kwargs["revision"] == "5617a9f61b028005a4858fdac845db406aefb181"
119+
model_loader = MagicMock()
120+
tokenizer_loader = MagicMock()
121+
monkeypatch.setattr(transformers.AutoModel, "from_pretrained", model_loader)
122+
monkeypatch.setattr(transformers.AutoTokenizer, "from_pretrained", tokenizer_loader)
123+
adapter = BGEM3FlashAdapter(**kwargs)
124+
head_loader = MagicMock()
125+
monkeypatch.setattr(adapter, "_load_linear_layers", head_loader)
126+
127+
adapter.load("cuda:0")
128+
129+
model_loader.assert_called_once_with(
130+
"BAAI/bge-m3",
131+
torch_dtype=torch.float16,
132+
attn_implementation="eager",
133+
revision=config.hf_revision,
134+
)
135+
tokenizer_loader.assert_called_once_with("BAAI/bge-m3", revision=config.hf_revision)
136+
head_loader.assert_called_once_with("BAAI/bge-m3", torch.float16, "cuda:0")
137+
138+
@pytest.mark.parametrize("name", ["default", "dense", "sparse", "multivector"])
139+
def test_flash_profiles_preserve_recipe(self, config: ModelConfig, name: str) -> None:
140+
profile = config.resolve_profile(name)
141+
assert profile.adapter_path == "sie_server.adapters.bge_m3_flash:BGEM3FlashAdapter"
142+
assert profile.max_batch_tokens == 16384
143+
assert profile.loadtime == {}
144+
expected_runtime: dict[str, Any] = {"pooling": "cls", "normalize": True}
145+
if name != "default":
146+
expected_runtime["output_types"] = [name]
147+
assert profile.runtime == expected_runtime
148+
assert config.max_sequence_length == 8192
149+
assert config.dims == {"dense": 1024, "sparse": 250002, "multivector": 1024}
150+
151+
@pytest.mark.parametrize(
152+
("precision", "expected_dtype"),
153+
[("float16", torch.float16), ("bfloat16", torch.bfloat16)],
154+
)
155+
def test_explicit_flash_precision_remains_supported(
156+
self, precision: ComputePrecision, expected_dtype: torch.dtype
157+
) -> None:
158+
adapter = BGEM3FlashAdapter(compute_precision=precision)
159+
assert adapter._resolve_dtype() == expected_dtype
160+
96161

97162
class TestBGEM3EmbeddingParity:
98163
@pytest.mark.parametrize("dtype", [torch.float16, torch.bfloat16, torch.float32])

‎packages/sie_server/tests/test_all_models.py‎

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -451,27 +451,26 @@ def test_openai_clip_vit_large_patch14_image_dense() -> None:
451451
# =============================================================================
452452

453453

454-
_BGE_M3_CPU_BFLOAT16 = pytest.mark.xfail(
454+
_BGE_M3_CPU_FLOAT16 = pytest.mark.xfail(
455455
reason=(
456-
"The default profile's compute_precision: bfloat16 also applies on CPU, so BGEM3Adapter runs in "
457-
"bfloat16 and drifts from the float32 FlagEmbedding output pinned here (bge_m3_flag still matches it)"
456+
"The default profile's compute_precision: float16 also applies on CPU, so BGEM3Adapter's "
457+
"dense and multivector outputs differ from the float32 FlagEmbedding reference pinned here"
458458
),
459459
raises=_NumericalReferenceMismatchError,
460460
strict=True,
461461
)
462462

463463

464-
@_BGE_M3_CPU_BFLOAT16
464+
@_BGE_M3_CPU_FLOAT16
465465
def test_baai_bge_m3_dense() -> None:
466466
_assert_dense("BAAI/bge-m3", 1024, [0.001247406005859375, 0.0228271484375, -0.02349853515625])
467467

468468

469-
@_BGE_M3_CPU_BFLOAT16
470469
def test_baai_bge_m3_sparse() -> None:
471470
_assert_sparse("BAAI/bge-m3", [3034], [0.342041015625])
472471

473472

474-
@_BGE_M3_CPU_BFLOAT16
473+
@_BGE_M3_CPU_FLOAT16
475474
def test_baai_bge_m3_multivector() -> None:
476475
_assert_multivector("BAAI/bge-m3", 1024, [0.01641845703125, 0.0304718017578125, -0.036468505859375])
477476

‎packages/sie_server/tests/test_all_models_assertions.py‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,18 @@
99
from packages.sie_server.tests import test_all_models as models
1010

1111

12+
@pytest.mark.parametrize("kind", ["dense", "sparse", "multivector"])
13+
def test_bge_m3_cpu_numeric_xfail_applies_only_to_dense_and_multivector(kind: str) -> None:
14+
test = getattr(models, f"test_baai_bge_m3_{kind}")
15+
markers = [mark for mark in getattr(test, "pytestmark", []) if mark.name == "xfail"]
16+
if kind == "sparse":
17+
assert markers == []
18+
else:
19+
assert len(markers) == 1
20+
assert markers[0].kwargs["strict"] is True
21+
assert markers[0].kwargs["raises"] is models._NumericalReferenceMismatchError
22+
23+
1224
@pytest.mark.parametrize("kind", ["dense", "sparse", "multivector"])
1325
@pytest.mark.parametrize("defect", [None, "absent", "shape", "nonfinite", "numerical"])
1426
def test_bge_m3_xfail_preserves_output_structure(
@@ -37,9 +49,9 @@ def test_bge_m3_xfail_preserves_output_structure(
3749
output = SimpleNamespace(**{kind: payload})
3850
monkeypatch.setattr(models, "_get_adapter", lambda _: SimpleNamespace(encode=lambda *_args, **_kwargs: output))
3951

40-
expected_failure = models._BGE_M3_CPU_BFLOAT16.kwargs["raises"]
52+
expected_failure = models._BGE_M3_CPU_FLOAT16.kwargs["raises"]
4153
assert expected_failure is models._NumericalReferenceMismatchError
42-
assert models._BGE_M3_CPU_BFLOAT16.kwargs["strict"] is True
54+
assert models._BGE_M3_CPU_FLOAT16.kwargs["strict"] is True
4355
if defect is None:
4456
check()
4557
elif defect == "numerical":

0 commit comments

Comments
 (0)