Train Sentence Transformers
Hugging FaceOfficialPublished by Hugging Face
- Skill
- Workflow
- Data and AI
- Apache-2.0
- Medium risk
- Has scripts
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a standardized approach to training various embedding and ranking models using the sentence-transformers framework. It acts as a routing system that directs users to specific production templates and technical references based on the chosen model architecture. The workflow covers the entire lifecycle from model selection and data preparation to loss function configuration, evaluation, and publishing to the Hugging Face Hub.
What it does
- Routes users to appropriate training templates for bi-encoders, cross-encoders, sparse encoders, and multi-vector encoders.
- Provides technical references for loss functions, evaluators, and model architectures.
- Offers guidance on hard-negative mining and dataset formatting for training.
- Includes instructions for hardware-specific configurations and Hugging Face Hub integration.
- Defines mandatory script requirements such as smoke testing, logging, and verdict reporting.
When to use it
- When you need to train or fine-tune a sentence-transformers model for retrieval, similarity, or ranking tasks.
- When you are unsure which model architecture (e.g., bi-encoder vs. cross-encoder) is best suited for your specific use case.
- When you require a structured, repeatable process for training and evaluating embedding models.
- When you need to integrate advanced training techniques like distillation, LoRA, or Matryoshka embeddings.
Advantages
- Enforces consistent training practices through standardized production templates.
- Reduces common errors by providing specific references for loss-to-data-shape mapping.
- Facilitates systematic experimentation with built-in logging and verdict reporting.
- Supports a wide range of model types including modern late-interaction and sparse architectures.
Usage examples
- “I need to train a bi-encoder for semantic search on my internal documentation.”
- The agent will identify the [SentenceTransformer] type, provide the relevant loss and evaluator references, and guide you to the bi-encoder production template.
- “How do I implement a two-stage retrieval system using a reranker?”
- The agent will direct you to the [CrossEncoder] documentation and template, explaining how to use it to score pairs for two-stage retrieval.
- “I want to train a SPLADE model for sparse retrieval.”
- The agent will provide the [SparseEncoder] references, including the required SpladeLoss wrapper and specific evaluators for sparse retrieval.
- “How can I improve my retrieval model using hard negatives?”
- The agent will guide you to the hard-negative mining script and explain how to generate n-tuple datasets for training.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/huggingface/train-sentence-transformers/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip train-sentence-transformers.zip -d .agents/skills
Documentation by Hugging Face
Train a sentence-transformers Model
This SKILL.md is a router, not a manual. It tells you which references and example scripts to load for your task. The actual content (recommended losses, evaluators, training-script structure, model selection, training-arg knobs, troubleshooting) lives in references/ and scripts/.
Do not synthesize a training script from this file alone. Open the per-type production template (scripts/train_<type>_example.py) and copy it as your starting point. The templates contain load-bearing scaffolding (autocast helper, model-card class, logger silencing list, force=True, seed, TF32, version-compatible imports, named-evaluator metric handling) that prior agent runs have repeatedly missed when rolling their own from a synthesized snippet.
1. Identify the model type
| Tag | Class | What it does | When to pick |
|---|---|---|---|
| [SentenceTransformer] | SentenceTransformer (bi-encoder) | Maps each input to a fixed-dim dense vector | Retrieval, similarity, clustering, classification, paraphrase mining, dedup |
| [CrossEncoder] | CrossEncoder (reranker) | Scores (query, passage) pairs jointly | Two-stage retrieval (rerank top-100 from bi-encoder), pair classification |
| [SparseEncoder] | SparseEncoder (SPLADE) | Sparse vectors over the vocabulary | Learned-sparse retrieval, inverted-index backends (Elasticsearch / OpenSearch / Lucene) |
| [MultiVectorEncoder] | MultiVectorEncoder (ColBERT) | One embedding per token, scored with MaxSim | Late-interaction retrieval, recall gains over bi-encoders at higher storage cost, multimodal (ColPali / ColQwen2) |
Tiebreakers when the request is ambiguous: "embedding model" / "vector search" / "similarity" → [SentenceTransformer]. "rerank" / "ranker" / "two-stage" → [CrossEncoder]. "SPLADE" / "sparse" / "inverted index" → [SparseEncoder]. "ColBERT" / "late interaction" / "multi-vector" / "MaxSim" / "ColPali" / "ColQwen" → [MultiVectorEncoder]. If still unclear, ask.
2. Required reading
Read these in full before writing any code. Do not triage by perceived relevance.
Per-type: always required
[SentenceTransformer]
references/losses_sentence_transformer.md: loss-to-data-shape mapping,BatchSamplers.NO_DUPLICATESrequirement for MNRL-family,Cached*↔gradient_checkpointingincompatibility.references/evaluators_sentence_transformer.md: evaluator-to-task mapping,metric_for_best_modelkey construction (named vs unnamed), per-evaluatorprimary_metricvalues.references/model_architectures.md: encoder vs decoder vs static vs Router pipelines, pooling rules (mean / cls / lasttoken), auto-mean-pooling behavior for fresh-start MLM bases.scripts/train_sentence_transformer_example.py: production template. Copy this as your starting point.
[CrossEncoder]
references/losses_cross_encoder.md: pointwise / pairwise / listwise / distillation,pos_weightderivation,activation_fn=Identity()mandatory for non-BCE losses (silent eval-rank collapse otherwise).references/evaluators_cross_encoder.md:CrossEncoderRerankingEvaluatorrecipe, named-evaluator key formateval_{name}_{primary_metric}.scripts/train_cross_encoder_example.py: production template. Copy this as your starting point.
[SparseEncoder]
references/losses_sparse_encoder.md:SpladeLosswrapper requirement, FLOPS regularizer weights, smoke-test active-dim ramp behavior.references/evaluators_sparse_encoder.md:SparseNanoBEIREvaluator(English-only) and the in-domain alternative,eval_{name}_{primary_metric}key format.scripts/train_sparse_encoder_example.py: production template. Copy this as your starting point.
[MultiVectorEncoder]
references/losses_multi_vector_encoder.md: MaxSim scoring, scale choice per scoring mode (scale=1.0for MaxSim, roughly the average query length for MeanMaxSim), MNRL / CachedMNRL / MarginMSE / DistillKLDiv, XTR-vs-ColBERT scoring, CachedMNRL ↔gradient_checkpointingincompatibility.references/evaluators_multi_vector_encoder.md:MultiVectorNanoBEIREvaluator(English-only) and the in-domain alternative,eval_NanoBEIR_mean_maxsim_ndcg@10key format, distillation-eval spearman variant.scripts/train_multi_vector_encoder_example.py: production template. Copy this as your starting point.
Cross-cutting: always required (regardless of task)
references/training_args.md:TrainingArgumentsknobs, precision rules (load fp32 + autocast bf16/fp16, nevertorch_dtype=bfloat16),warmup_steps(float) vs deprecatedwarmup_ratio,save_stepsmust be a multiple ofeval_stepsforload_best_model_at_end, schedulers, HPO, tracker, resume, hub-push variants.references/dataset_formats.md: column-matching rules (label name auto-detection, column-order-not-name), reshaping recipes, hard-negative mining options.references/base_model_selection.md: discovery commands, per-type model namespaces, ModernBERT-familymax_seq_length=8192trap,datasets >= 4script-loader rejection, non-English starting-point shortcuts.references/troubleshooting.md: symptom-indexed failure recipes. Skim the section headings on every run, even a healthy one. The "Metrics don't improve" and "Hub push fails" entries cover bugs that bite frequently and are cheaper to recognize before they fire than to debug after.
Cross-cutting: load when applicable
references/hardware_guide.md: VRAM sizing, multi-GPU, FSDP / DeepSpeed, HF Jobs flavors. Required for >24GB models, multi-GPU, or HF Jobs runs.references/hf_jobs_execution.md: required when running on HF Jobs.references/prompts_and_instructions.md: required when using prompt-tuned bases (E5, BGE, GTE, Qwen3-Embedding, Instructor, Nomic, etc.) or addingquery:/passage:style prefixes.
Variant scripts (open when the task matches)
[SentenceTransformer]
scripts/train_sentence_transformer_<matryoshka|multi_dataset|with_lora|distillation|make_multilingual|static_embedding>_example.py.[CrossEncoder]
scripts/train_cross_encoder_<distillation|listwise>_example.py.[SparseEncoder]
scripts/train_sparse_encoder_distillation_example.py.Hard-negative mining CLI:
scripts/mine_hard_negatives.py.
3. Defaults
Override only if the user specifies otherwise:
Local execution. Pitch HF Jobs only if local hardware can't fit the job.
Single run. After it completes, propose experimentation if the user would benefit (weak/marginal verdict, "see how high you can push it" framing, etc.). Iteration rules in
references/training_args.md(Experimentation section).Public Hub push at end-of-run, wrapped in try-except. On HF Jobs (ephemeral env) ALSO enable in-trainer push (
push_to_hub=True+hub_strategy="every_save"). Details inreferences/hf_jobs_execution.md.
4. Constraints the produced script must satisfy
These are non-negotiable contracts. Implementation lives in the production templates and references. Do not reinvent.
Capture the pre-training evaluator score as
baseline_evalbeforetrainer.train().Emit a single end-of-run line:
VERDICT: WIN|MARGINAL|REGRESSION | score=... | baseline=... | delta=.... A monitor scrapes for this.Silence
httpx,httpcore,huggingface_hub,urllib3,filelock,fsspecto WARNING (otherwise HF download URLs flood the agent's context).Tee logs to
logs/{RUN_NAME}.log.End with
model.push_to_hub(...)wrapped intry/except.Smoke-test before any long run (
max_steps=1+ tiny dataset slice). The production templates show one common pattern (SMOKE_TESTenv var).[CrossEncoder] Include
EarlyStoppingCallback(patience>=3). CE rerankers often peak mid-training and regress.[SparseEncoder] Log
query_active_dims/corpus_active_dimson the verdict line. High nDCG with collapsed sparsity is not a win. The keys come back name-prefixed (e.g...._query_active_dims). Use suffix matching to pluck them. See the SPARSE production template for the exact pattern.[MultiVectorEncoder] Match
scaleto the scoring mode on any MNRL-family loss: near1.0for unnormalized MaxSim (do not copyscale=20.0from bi-encoder MNRL), roughly the average query length with length-normalized MeanMaxSim, since each score is divided by its query's token count.XTRScoresis a train-onlysimilarity_fct: the evaluators reject it, so evaluation always scores with MaxSim, including for XTR-trained models.
5. Workflow
Identify the model type (§1). Ask if ambiguous.
Load the §2 required-reading files for that type.
Open
scripts/train_<type>_example.pyand copy it as your starting point.Replace
MODEL_NAME,DATASET_NAME,RUN_NAME, the loss, and the evaluator with the user's task. Cross-check loss/data-shape match againstreferences/losses_<type>.md. Cross-check themetric_for_best_modelkey againstreferences/evaluators_<type>.md(named evaluators format the key aseval_{name}_{primary_metric}).Smoke-test (
max_steps=1).Run.
After the run, append to
logs/experiments.mdand propose iteration if the verdict is weak/marginal.
Prerequisites
pip install "sentence-transformers[train]>=5.0" # add [train,image] / [audio] / [video] for [SentenceTransformer] multimodal
# [MultiVectorEncoder] requires >=6.0
pip install trackio # optional tracker (or wandb / tensorboard / mlflow)
hf auth login # or set HF_TOKEN with write scope (for Hub push)GPU strongly recommended. CPU works only for demos and [SentenceTransformer] StaticEmbedding.
Files
- ATTRIBUTION.mdAdded by AutoGineer898 B
- LICENSELicence file added by AutoGineer11.1 KiB
- SKILL.md10.3 KiB
- references/base_model_selection.md7.5 KiB
- references/dataset_formats.md6.3 KiB
- references/evaluators_cross_encoder.md5.5 KiB
- references/evaluators_multi_vector_encoder.md6.6 KiB
- references/evaluators_sentence_transformer.md5.8 KiB
- references/evaluators_sparse_encoder.md4.9 KiB
- references/hardware_guide.md5.9 KiB
- references/hf_jobs_execution.md7.1 KiB
- references/losses_cross_encoder.md9.5 KiB
- references/losses_multi_vector_encoder.md10.5 KiB
- references/losses_sentence_transformer.md10.7 KiB
- references/losses_sparse_encoder.md5.1 KiB
- references/model_architectures.md9.0 KiB
- references/prompts_and_instructions.md6.4 KiB
- references/training_args.md15.0 KiB
- references/troubleshooting.md12.9 KiB
- scripts/mine_hard_negatives.pyScript8.3 KiB
- scripts/train_cross_encoder_distillation_example.pyScript9.2 KiB
- scripts/train_cross_encoder_example.pyScript9.0 KiB
- scripts/train_cross_encoder_listwise_example.pyScript10.2 KiB
- scripts/train_multi_vector_encoder_example.pyScript8.8 KiB
- scripts/train_sentence_transformer_distillation_example.pyScript11.9 KiB
- scripts/train_sentence_transformer_example.pyScript7.5 KiB
- scripts/train_sentence_transformer_make_multilingual_example.pyScript11.5 KiB
- scripts/train_sentence_transformer_matryoshka_example.pyScript7.1 KiB
- scripts/train_sentence_transformer_multi_dataset_example.pyScript9.9 KiB
- scripts/train_sentence_transformer_static_embedding_example.pyScript10.3 KiB
- scripts/train_sentence_transformer_with_lora_example.pyScript10.3 KiB
- scripts/train_sparse_encoder_distillation_example.pyScript9.4 KiB
- scripts/train_sparse_encoder_example.pyScript8.1 KiB
references/troubleshooting.md
Troubleshooting
Common failures in sentence-transformers training, with root causes and fixes. Organized by symptom.
Out of memory (OOM)
Symptom: torch.cuda.OutOfMemoryError or CUDA out of memory.
Fixes in order:
Reduce
per_device_train_batch_size. For MNRL, compensate viaCachedMultipleNegativesRankingLoss(model, mini_batch_size=...)with a large outer batch.Set
gradient_accumulation_stepsto accumulate gradients over multiple smaller batches (for non-contrastive losses).Enable
gradient_checkpointing=True. ~30% slower, ~40% less activation memory. Incompatible withCached*losses.Use
bf16=Trueinstead of fp32 (if your GPU supports Ampere+).Reduce
max_seq_lengthon the transformer module:model[0].max_seq_length = 128.Use LoRA (
peft) for large decoder bases. See../scripts/train_sentence_transformer_with_lora_example.py(docstring covers when to use, hyperparams, QLoRA, gotchas).Move to a bigger GPU or multi-GPU (
accelerate launch).
See also: hardware_guide.md for VRAM estimates by batch size.
Loss is NaN or Inf
Symptom: training loss printed as nan or inf, or suddenly jumps to a huge value.
Fixes:
Drop learning rate first. Try
5e-6or1e-6.Enable
warmup_steps=0.1(a float< 1is interpreted as a fraction of total steps), or set an absolutewarmup_steps=500.Switch fp16 -> bf16 (more numerically stable). If stuck on fp16 (older GPU), try disabling fp16 for a sanity run.
Check the dataset for broken rows: empty strings, NaN label values, mismatched column counts. Inspect a few rows with
print(dataset[:5]).For custom losses or unusual base models (very long context), consider adding
max_grad_norm=1.0to the training args.Check tokenization: some tokenizers emit no tokens for certain unicode / whitespace-only inputs, which can cause downstream NaN in mean pooling.
Metrics don't improve / are at baseline
Symptom: eval metrics after training are the same as before.
Fixes:
Re-run dataset inspector with
--loss <your-loss>. Most likely cause: column order wrong, label column not detected, or loss expects a different shape.For retrieval: your negatives are too easy. Mine hard negatives (
scripts/mine_hard_negatives.py).Check
metric_for_best_model. If the key doesn't match what the evaluator writes, the trainer silently uses the final checkpoint (not the best).Confirm
BatchSamplers.NO_DUPLICATESis set for MNRL-style losses. Without it, the in-batch negative signal is corrupted.Base model is wrong for the task (e.g. decoder-only LLM for short-text STS). Try a different base.
Learning rate too low. Default
2e-5works for encoders. LoRA wants1e-4+. Static embeddings want about2e-1(much higher than transformers).Dataset too small for the chosen loss. Contrastive losses need >10k pairs to be meaningful.
Training hangs at the first eval
Symptom: training starts, then hangs indefinitely at the first evaluation step.
Fix: you set eval_strategy="steps" or "epoch" but either didn't pass eval_dataset or passed an empty one. Either provide an eval_dataset or set eval_strategy="no".
Training hangs at startup (multi-GPU)
Symptom: accelerate launch runs, prints "Found X GPUs" + model-loading messages, then hangs.
Fixes:
If using a custom dataset class, ensure
__len__is implemented and returns a consistent length across processes.If using
batch_sampler=BatchSamplers.NO_DUPLICATESwith a very small dataset relative to the world size, batches may not form. Use a larger dataset or smaller per-device batch.Check for mismatched PyTorch / CUDA versions across nodes.
nvidia-smi+python -c "import torch; print(torch.version.cuda)"on each node.NCCL timeout. Set
NCCL_TIMEOUT=300(seconds) env var.
CachedMultipleNegativesRankingLoss crashes
Symptom: error like "element 0 of tensors does not require grad", or a cryptic autograd error.
Fix: you have gradient_checkpointing=True. The cached losses do their own forward/backward orchestration. Gradient checkpointing conflicts with it. Disable gradient_checkpointing.
Same applies to CachedSpladeLoss, CachedGISTEmbedLoss, and any other Cached* loss.
Hub push fails
Symptom: HTTPError: 401 or 403 during push_to_hub.
Fixes:
Run
hf auth whoami. If it fails, runhf auth login.Token needs write permission. Regenerate from https://huggingface.co/settings/tokens.
Repo either must exist and you have write access, or
hub_private_repo=True/Falseis set so the library can create it.On HF Jobs: pass
secrets={"HF_TOKEN": "$HF_TOKEN"}on the job submission.
Tracker (Trackio / W&B / TensorBoard) not logging
Symptom: training runs but no metrics appear in the tracker UI.
Fixes:
Trackio: confirm
pip install trackiosucceeded. No login step. Trackio uses yourHF_TOKEN(set byhf auth loginor theHF_TOKENenv var). On HF Jobs,HF_TOKENmust be insecrets.W&B: confirm
wandb loginsucceeded, orWANDB_API_KEYenv var is set. On HF Jobs,WANDB_API_KEYmust be insecrets.report_tonot set to the right tracker:report_to="trackio"(or"wandb", or a list like["trackio", "tensorboard"]).TensorBoard: check
logging_dir(defaults tooutput_dir/runs/<timestamp>). Point TB at the parent.
Base model loads but encode produces garbage
Symptom: model.encode(["test"]) returns constant vectors, or all-zeros, or NaN.
Fixes:
You loaded a classification fine-tune as a base (e.g. a BERT fine-tuned on SQuAD). The CLS head is a QA head, not a usable pooling layer. Use the underlying pretrained encoder (
bert-base-uncased), not the task-specific checkpoint.For decoder models: you're using mean pooling on causal attention. Switch to last-token pooling.
For SPLADE: the model's MLM head isn't initialized properly. Make sure the base has
AutoModelForMaskedLMcompatibility.
Dataset loads but eval is trivially correct
Symptom: eval metric is 1.0 (perfect) from the first evaluation step.
Fix: your eval set overlaps the train set. Check dataset.train_test_split(test_size=...) was called correctly, or that the Hub dataset's train vs. dev splits are actually disjoint.
Model-card generation fails
Symptom: warning about model-card generation, or README.md is missing after save_pretrained.
Fixes:
codecarbonmay be attempting to write emissions and failing. SetCODECARBON_LOG_LEVEL=erroror uninstall codecarbon.Some training state couldn't be serialized (custom objects with unusual types). Pass
model_card_data=SentenceTransformerModelCardData(...)with explicit fields to bypass inference.
num_labels mismatch on CrossEncoder
Symptom: BinaryCrossEntropyLoss raises about mismatched dims, or CrossEntropyLoss complains.
Fix: num_labels=1 goes with BinaryCrossEntropyLoss. num_labels>=2 goes with CrossEntropyLoss. Set CrossEncoder("...", num_labels=1) for BCE.
CrossEncoder eval nDCG crashes after distillation / listwise / pairwise training
Symptom: training loss looks healthy, baseline eval looked fine, but post-training eval nDCG drops a lot (e.g. 0.59 → 0.14). Every checkpoint after the first eval is below baseline.
Root cause: the default Sigmoid activation function on CrossEncoder(num_labels=1, ...) saturates raw logits >5 to ~1.0. Distillation/listwise/pairwise losses (MSELoss, MarginMSELoss, LambdaLoss, RankNetLoss, ListNetLoss, ListMLELoss, PListMLELoss, ADRMSELoss) operate on raw logits. Once the model learns to push positives past the saturation point, ranking information is lost.
Fix: construct the model with an Identity activation:
import torch.nn as nn
model = CrossEncoder("...", num_labels=1, activation_fn=nn.Identity())Keep the default Sigmoid only for BinaryCrossEntropyLoss (which uses BCE-with-logits internally and wants sigmoidable inputs).
LambdaLoss training loss is tiny (e.g. 1e-4): is training broken?
Symptom: with LambdaLoss(model, weighting_scheme=NDCGLoss2PPScheme()) and large K (>=64), training loss prints in the 1e-3 to 1e-5 range.
Root cause: NDCGLoss2PPScheme normalizes by the discount-weighted pair count, which scales roughly with K. The numeric magnitude of the loss isn't the signal you should track.
Fix: ignore training loss for LambdaLoss. Watch the eval metric (eval_NanoBEIR_R100_mean_ndcg@10 or your metric_for_best_model) instead. If eval is moving in the right direction and loss is "too small", that's expected.
LambdaLoss OOM: what to drop first
Symptom: CUDA out of memory during a LambdaLoss training step, especially at K>=64.
Recovery order:
Lower
mini_batch_sizeon the loss first. The internal forward chunking preserves the K-list semantic. This is the cheapest knob and doesn't change the experiment.Lower
per_device_train_batch_sizeand compensate withgradient_accumulation_stepsto keep total batch fixed.Reduce K (the candidate-list length per query) only as a last resort. Lowering K changes what the loss is computing. This is an experimental change, not a memory tweak.
For very large K (>=128), NDCGLoss2PPScheme materializes O(K²) weight buffers per query that aren't covered by the forward chunking, so even small mini_batch_size may not be enough. At that point K is the right knob.
Loading a model with a custom inline nn.Module raises ImportError
Symptom: training and saving via train.py works fine. Loading the saved model from any other script (predict.py, a notebook, or another package) fails with:
ImportError: Module "__main__" does not define a "ClassifierHead" attributeRoot cause: when a custom nn.Module is defined inline in a script, Python records its qualname as __main__.ClassifierHead. ST writes that qualname into modules.json at save time. Loading from a different entry point can't resolve __main__.ClassifierHead. The class doesn't exist in the loader's __main__.
Fixes (any one):
Move the class to an importable module:
from my_pkg.heads import ClassifierHead. Save again somodules.jsonrecordsmy_pkg.heads.ClassifierHead.Build the same shape using stock ST modules (
Dense + LayerNorm + Dense) instead of a custom class. Those are always loadable.Document that the model is only loadable from the same script (acceptable for one-off experiments, not for shipping models).
SPLADE embeddings are dense (not sparse)
Symptom: after training, (embedding != 0).sum(dim=-1) is in the thousands, not ~30-250.
Fixes:
You're missing the
SpladeLosswrapper.SparseMultipleNegativesRankingLossalone doesn't add FLOPS regularization. Wrap:SpladeLoss(model, loss=inner_loss, query_regularizer_weight=5e-5, document_regularizer_weight=3e-5).Regularizer weights too low. Increase to 1e-4 or higher.
Scheduler wiped out early.
SpladeRegularizerWeightSchedulerCallbackramps weights from 0 to target over the first ~33% of training (warmup_ratio=1/3by default, configurable). On very short runs this never reaches target. Either train longer or setquery_regularizer_weight/document_regularizer_weighthigher to compensate.
ValueError: The dataset has ... columns but the loss expects N
Fix: column count mismatch. Drop extra columns (dataset.remove_columns([...])) or reorder with select_columns. Names don't matter. Count and order do.
Encoding on CPU is painfully slow
Symptom: a few dozen sentences per second instead of 1000s.
Fixes:
Ensure the model is on GPU:
model.to("cuda")(ordevice_map="auto"when loading).For genuine CPU inference (no GPU available), consider switching to a
StaticEmbedding-based model, ~1000x faster on CPU than a transformer.
Hub model loads, but model.encode(prompt_name="query") acts like no prompt was applied
Fix: the saved model doesn't have prompts in config_sentence_transformers.json. When training, set model.prompts = args.prompts before save_pretrained, or use SentenceTransformerModelCardData(prompts=...).
accelerate launch runs only on one GPU
Fix: run accelerate config first, set number of GPUs and precision. Or pass explicitly: accelerate launch --multi_gpu --num_processes=4 train.py.
Cached loss + PEFT adapter fails to backprop
Symptom: "None of the inputs have requires_grad=True" when using Cached* loss with a LoRA adapter.
Fix: after add_adapter, call:
model.transformers_model.enable_input_require_grads()This ensures gradient flow through the frozen base + trainable adapter.
Related reference docs
training_args.md(shared): the args that affect all of the above.hardware_guide.md(shared): VRAM sizing and multi-GPU.dataset_formats.md(shared): column/loss validation.losses_sentence_transformer.md/losses_cross_encoder.md/losses_sparse_encoder.md(per-model-type catalogs): loss-specific quirks.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs Python
Security
What our scanner noticed· Medium risk
- Instructions that use the network
- Downloads piped into a shell
- Scripts that your agent may run
This skill includes scripts that your agent may run. Read them before you use it.
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- Hugging Face
- Publisher
- Hugging Face (Official)
- Source
- huggingface/skills · skills/train-sentence-transformers · commit 25910b3
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Hugging Face or Hugging Face.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download train-sentence-transformers.zip