Instructions to use netprojects/Nemotron-3.5-Rerank-8B-GGUF with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use netprojects/Nemotron-3.5-Rerank-8B-GGUF with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible embeddings server: llama serve -hf netprojects/Nemotron-3.5-Rerank-8B-GGUF:Q4_K_M --embeddings
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible embeddings server: llama serve -hf netprojects/Nemotron-3.5-Rerank-8B-GGUF:Q4_K_M --embeddings
Build from source code
git clone https://github.com/ggml-org/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-app # Start a local OpenAI-compatible embeddings server: ./build/bin/llama serve -hf netprojects/Nemotron-3.5-Rerank-8B-GGUF:Q4_K_M --embeddings
- Llama new
- LM Studio
- Jan
- Ollama
How to use netprojects/Nemotron-3.5-Rerank-8B-GGUF with Ollama:
ollama run hf.co/netprojects/Nemotron-3.5-Rerank-8B-GGUF:Q4_K_M
- Unsloth Desktop
- Docker Model Runner
How to use netprojects/Nemotron-3.5-Rerank-8B-GGUF with Docker Model Runner:
docker model run hf.co/netprojects/Nemotron-3.5-Rerank-8B-GGUF:Q4_K_M
- Lemonade
How to use netprojects/Nemotron-3.5-Rerank-8B-GGUF with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull netprojects/Nemotron-3.5-Rerank-8B-GGUF:Q4_K_M
Run and chat with the model
lemonade run user.Nemotron-3.5-Rerank-8B-GGUF-Q4_K_M
List all available models
lemonade list
- Atomic Chat
File size: 5,791 Bytes
50bfecf | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | diff --git a/conversion/__init__.py b/conversion/__init__.py
index 3976e03..4c7d5cc 100644
--- a/conversion/__init__.py
+++ b/conversion/__init__.py
@@ -213,6 +213,8 @@ TEXT_MODEL_MAP: dict[str, str] = {
"Ministral3Model": "mistral3",
"Mistral3ForConditionalGeneration": "mistral3",
"Mistral3Model": "mistral3",
+ "Mistral3ForSequenceClassification": "mistral3",
+ "Ministral3ForSequenceClassification": "mistral3",
"MistralLarge4ForConditionalGeneration": "mistral4",
"VoxtralRealtimeForConditionalGeneration": "mistral3",
"MistralForCausalLM": "llama",
diff --git a/conversion/mistral3.py b/conversion/mistral3.py
index 6c771b2..e77bef4 100644
--- a/conversion/mistral3.py
+++ b/conversion/mistral3.py
@@ -16,6 +16,8 @@ from .llama import LlamaModel
"Mistral3Model",
"Ministral3ForCausalLM",
"Ministral3Model",
+ "Mistral3ForSequenceClassification", # LOCAL PATCH
+ "Ministral3ForSequenceClassification", # LOCAL PATCH
)
@ModelBase.example("mistralai/Mistral-Small-3.1-24B-Instruct-2503", "hf-tiny-v2/tiny-random-Ministral3ForCausalLM", "nvidia/Nemotron-3-Embed-1B-BF16", "nvidia/Nemotron-3.5-Embed-1B-BF16")
class Mistral3Model(TextModel):
@@ -40,13 +42,28 @@ class Mistral3Model(TextModel):
self.gguf_writer.add_add_eos_token(False)
def get_vocab_base_pre(self, tokenizer) -> str:
- if self.origin_hf_arch == "Mistral3Model":
+ if self.origin_hf_arch in ("Mistral3Model", "Mistral3ForSequenceClassification", "Ministral3ForSequenceClassification"):
return "nemotron-3.5-embed"
return super().get_vocab_base_pre(tokenizer)
def set_gguf_parameters(self):
super().set_gguf_parameters()
self._try_set_pooling_type()
+ if self.is_rerank: # LOCAL PATCH: Nemotron rerank -> native RANK pooling (mean + cls.output)
+ self.gguf_writer.add_pooling_type(gguf.PoolingType.RANK)
+ self.gguf_writer.add_classifier_output_labels(["score"])
+ self.gguf_writer.add_chat_template([{"name": "rerank", "template": "query: {query}\n\npassage: {document}"}])
+
+ @property
+ def is_rerank(self) -> bool:
+ return "sequenceclassification" in (self.origin_hf_arch or "").lower()
+
+ def modify_tensors(self, data_torch, name, bid): # LOCAL PATCH: rerank score head -> cls.output
+ if name.endswith("score.weight"):
+ if self.is_rerank:
+ yield (gguf.TENSOR_NAMES[gguf.MODEL_TENSOR.CLS_OUT] + ".weight", data_torch)
+ return
+ yield from super().modify_tensors(data_torch, name, bid)
class Mistral4Model(DeepseekV2Model):
model_arch = gguf.MODEL_ARCH.MISTRAL4
@@ -64,14 +81,14 @@ class Mistral3Model(TextModel):
def __init__(self, dir_model, *args, **kwargs):
hparams = ModelBase.load_hparams(dir_model, is_mistral_format=False)
hf_arch = get_model_architecture(hparams, self.model_type)
- if hf_arch in ("Ministral3Model", "Mistral3Model"):
+ if hf_arch in ("Ministral3Model", "Mistral3Model", "Mistral3ForSequenceClassification", "Ministral3ForSequenceClassification"):
text_config = hparams.get("text_config", hparams)
if text_config.get("is_causal") is not False:
raise NotImplementedError(f"Expected a Nemotron Embed model for {hf_arch}, but is_causal is not False")
super().__init__(dir_model, *args, **kwargs)
if self.hparams.get("model_type") == "mistral4":
self.impl = Mistral3Model.Mistral4Model(dir_model, *args, **kwargs)
- elif self.hf_arch in ("Ministral3Model", "Mistral3Model"):
+ elif self.hf_arch in ("Ministral3Model", "Mistral3Model", "Mistral3ForSequenceClassification", "Ministral3ForSequenceClassification"):
self.impl = Mistral3Model.Mistral3EmbedNemotronModel(dir_model, *args, **kwargs)
else:
self.impl = Mistral3Model.Ministral3Model(dir_model, *args, **kwargs)
diff --git a/gguf-py/gguf/constants.py b/gguf-py/gguf/constants.py
index 1d67dc8..238b26a 100644
--- a/gguf-py/gguf/constants.py
+++ b/gguf-py/gguf/constants.py
@@ -5820,6 +5820,7 @@ MODEL_TENSORS: dict[MODEL_ARCH, list[MODEL_TENSOR]] = {
],
MODEL_ARCH.MISTRAL3: [
MODEL_TENSOR.TOKEN_EMBD,
+ MODEL_TENSOR.CLS_OUT,
MODEL_TENSOR.OUTPUT_NORM,
MODEL_TENSOR.OUTPUT,
MODEL_TENSOR.ROPE_FREQS,
diff --git a/src/models/mistral3.cpp b/src/models/mistral3.cpp
index af058d5..bbdad09 100644
--- a/src/models/mistral3.cpp
+++ b/src/models/mistral3.cpp
@@ -20,6 +20,11 @@ void llama_model_mistral3::load_arch_hparams(llama_model_loader & ml) {
}
}
+ // rank pooling (Nemotron rerank): mean pooling before cls_out
+ if (hparams.pooling_type_cls == LLAMA_POOLING_TYPE_UNSPECIFIED) {
+ hparams.pooling_type_cls = LLAMA_POOLING_TYPE_MEAN;
+ }
+
switch (hparams.n_layer()) {
case 26: type = LLM_TYPE_3B; break;
case 34: type = LLM_TYPE_8B; break;
@@ -38,6 +43,9 @@ void llama_model_mistral3::load_arch_tensors(llama_model_loader & ml) {
output = create_tensor(tn(LLM_TENSOR_OUTPUT, "weight"), {n_embd, n_vocab}, TENSOR_NOT_REQUIRED);
// if output is NULL, init from the input tok embed
+ // optional classifier head (rerank)
+ cls_out = create_tensor(tn(LLM_TENSOR_CLS_OUT, "weight"), {n_embd, hparams.n_cls_out}, TENSOR_NOT_REQUIRED);
+
if (output == NULL) {
output = create_tensor(tn(LLM_TENSOR_TOKEN_EMBD, "weight"), {n_embd, n_vocab}, TENSOR_DUPLICATED);
}
|