Text Generation
Transformers
Safetensors
English
modernbert
fill-mask
sentiment-control
continuous-control
controllable-text-generation
encoder-generation
non-autoregressive
masked-language-model
text-style-transfer
data-augmentation
emnlp2026
Instructions to use shawhed/SenseShift-large with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use shawhed/SenseShift-large with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="shawhed/SenseShift-large")# Load model directly from transformers import AutoTokenizer, AutoModelForMaskedLM tokenizer = AutoTokenizer.from_pretrained("shawhed/SenseShift-large") model = AutoModelForMaskedLM.from_pretrained("shawhed/SenseShift-large", device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use shawhed/SenseShift-large with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "shawhed/SenseShift-large" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "shawhed/SenseShift-large", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/shawhed/SenseShift-large
- SGLang
How to use shawhed/SenseShift-large with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "shawhed/SenseShift-large" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "shawhed/SenseShift-large", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "shawhed/SenseShift-large" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "shawhed/SenseShift-large", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use shawhed/SenseShift-large with Docker Model Runner:
docker model run hf.co/shawhed/SenseShift-large
Emphasise encoder generation and continuous control; add measured sweep
Browse files
README.md
CHANGED
|
@@ -2,22 +2,63 @@
|
|
| 2 |
license: apache-2.0
|
| 3 |
base_model: answerdotai/ModernBERT-large
|
| 4 |
library_name: transformers
|
| 5 |
-
pipeline_tag:
|
|
|
|
| 6 |
tags:
|
| 7 |
- sentiment-control
|
|
|
|
| 8 |
- controllable-text-generation
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
- text-rewriting
|
| 10 |
- modernbert
|
|
|
|
| 11 |
language:
|
| 12 |
- en
|
| 13 |
---
|
| 14 |
|
| 15 |
# SenseShift-large
|
| 16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
SenseShift rewrites a sentence β or writes a new one β at **any sentiment you ask
|
| 18 |
for on a continuous β1.0 to +1.0 scale**, while keeping it consistent with the
|
| 19 |
surrounding text.
|
| 20 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
It is a masked language model fine-tuned from ModernBERT-large with an explicit
|
| 22 |
**control vocabulary**: 21 special tokens `[-1.0] β¦ [1.0]` on a 0.1 grid. At
|
| 23 |
training time every sentence is prefixed with its own VADER sentiment token and
|
|
@@ -112,9 +153,15 @@ itself is a stock `ModernBertForMaskedLM` and can be loaded with
|
|
| 112 |
|
| 113 |
- English only; trained on short narrative and review-style text.
|
| 114 |
- VADER supplies the sentiment labels, so the model inherits its lexicon-based
|
| 115 |
-
view of sentiment. `achieved_sentiment`
|
| 116 |
-
target
|
|
|
|
| 117 |
- The rewrite is length-bounded by `num_masks`, so very long sentences are
|
| 118 |
usually replaced by something shorter.
|
| 119 |
- Because the whole passage is re-encoded per mask fill, generation cost grows
|
| 120 |
with `num_masks Γ beam_size`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
license: apache-2.0
|
| 3 |
base_model: answerdotai/ModernBERT-large
|
| 4 |
library_name: transformers
|
| 5 |
+
pipeline_tag: text2text-generation
|
| 6 |
+
inference: false
|
| 7 |
tags:
|
| 8 |
- sentiment-control
|
| 9 |
+
- continuous-control
|
| 10 |
- controllable-text-generation
|
| 11 |
+
- encoder-generation
|
| 12 |
+
- non-autoregressive
|
| 13 |
+
- masked-language-model
|
| 14 |
+
- text-style-transfer
|
| 15 |
+
- sentiment-transfer
|
| 16 |
- text-rewriting
|
| 17 |
- modernbert
|
| 18 |
+
- emnlp2026
|
| 19 |
language:
|
| 20 |
- en
|
| 21 |
---
|
| 22 |
|
| 23 |
# SenseShift-large
|
| 24 |
|
| 25 |
+
> **Generation from an encoder, with continuous control.**
|
| 26 |
+
> An accepted EMNLP 2026 paper. Not a classifier, not a decoder β a masked LM
|
| 27 |
+
> that *writes* text at a sentiment you dial in.
|
| 28 |
+
|
| 29 |
SenseShift rewrites a sentence β or writes a new one β at **any sentiment you ask
|
| 30 |
for on a continuous β1.0 to +1.0 scale**, while keeping it consistent with the
|
| 31 |
surrounding text.
|
| 32 |
|
| 33 |
+
Two things make it unusual:
|
| 34 |
+
|
| 35 |
+
- **Continuous, not categorical.** Most sentiment-controlled generation offers
|
| 36 |
+
you `positive` / `negative` / `neutral`. SenseShift takes a *number* β 21
|
| 37 |
+
points on a 0.1 grid from β1.0 to +1.0. Sweeping the target over one sentence
|
| 38 |
+
of the example below, holding everything else fixed:
|
| 39 |
+
|
| 40 |
+
| target | achieved | rewritten sentence |
|
| 41 |
+
| ---: | ---: | --- |
|
| 42 |
+
| β1.0 | +0.0 | He said hello and took our order. |
|
| 43 |
+
| β0.9 | β0.8 | He looked sad and we felt bad. |
|
| 44 |
+
| β0.6 | β0.6 | He was very tired from working hard. |
|
| 45 |
+
| β0.3 | +0.0 | He said hello and took our order. |
|
| 46 |
+
| +0.0 | +0.0 | He served us some food and drinks. |
|
| 47 |
+
| +0.3 | +0.3 | We ordered a salad and shared it. |
|
| 48 |
+
| +0.6 | +0.5 | He smiled and gave us our drinks. |
|
| 49 |
+
| +0.9 | +0.8 | He smiled and thanked us for coming. |
|
| 50 |
+
| +1.0 | +0.8 | He smiled and thanked us for coming. |
|
| 51 |
+
|
| 52 |
+
The trend is monotone and most targets land within 0.1β0.2, but the control is
|
| 53 |
+
not exact: `β1.0` and `β0.3` both missed here, and the saturated ends (`Β±1.0`)
|
| 54 |
+
tend to collapse onto their `Β±0.9` neighbours. Treat the dial as a strong
|
| 55 |
+
steer, not a guarantee β and check `out.achieved_sentiment` if you need one.
|
| 56 |
+
- **The generator is an encoder.** Text generation is nearly always
|
| 57 |
+
autoregressive decoding. SenseShift generates by iteratively filling masked
|
| 58 |
+
positions in a bidirectional ModernBERT, so every token it writes is
|
| 59 |
+
conditioned on the text on *both* sides. That is what lets it drop a
|
| 60 |
+
replacement sentence into the middle of a passage and have it fit.
|
| 61 |
+
|
| 62 |
It is a masked language model fine-tuned from ModernBERT-large with an explicit
|
| 63 |
**control vocabulary**: 21 special tokens `[-1.0] β¦ [1.0]` on a 0.1 grid. At
|
| 64 |
training time every sentence is prefixed with its own VADER sentiment token and
|
|
|
|
| 153 |
|
| 154 |
- English only; trained on short narrative and review-style text.
|
| 155 |
- VADER supplies the sentiment labels, so the model inherits its lexicon-based
|
| 156 |
+
view of sentiment. `achieved_sentiment` usually lands within 0.1β0.2 of the
|
| 157 |
+
target, but individual targets can miss outright β see the sweep above. The
|
| 158 |
+
saturated ends (`Β±1.0`) are the least reliable.
|
| 159 |
- The rewrite is length-bounded by `num_masks`, so very long sentences are
|
| 160 |
usually replaced by something shorter.
|
| 161 |
- Because the whole passage is re-encoded per mask fill, generation cost grows
|
| 162 |
with `num_masks Γ beam_size`.
|
| 163 |
+
|
| 164 |
+
## Citation
|
| 165 |
+
|
| 166 |
+
Accepted to **EMNLP 2026**. A preprint and the full BibTeX entry will be linked
|
| 167 |
+
here once they are public.
|