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
| """Sentence segmentation, VADER scoring and output cleanup. | |
| Self-contained copies of the helpers the research repo keeps in | |
| ``generate_utils.py``, so the released package does not depend on it. | |
| """ | |
| from __future__ import annotations | |
| import re | |
| from functools import lru_cache | |
| from typing import List, Sequence, Tuple | |
| # The control vocabulary the model was trained with: 21 tokens on a 0.1 grid. | |
| SENTIMENT_GRID: Tuple[float, ...] = tuple(round(i / 10, 1) + 0.0 for i in range(-10, 11)) | |
| def sentiment_token(value: float) -> str: | |
| """Map a sentiment value to the special token the model expects.""" | |
| return f"[{snap_to_grid(value)}]" | |
| def snap_to_grid(value: float) -> float: | |
| """Clamp to [-1, 1] and round to the nearest 0.1 (never returns -0.0).""" | |
| value = float(value) | |
| if value != value: # NaN | |
| raise ValueError("sentiment must be a real number, got NaN") | |
| value = max(-1.0, min(1.0, value)) | |
| return round(value, 1) + 0.0 | |
| def _analyzer(): | |
| import nltk | |
| from nltk.sentiment import SentimentIntensityAnalyzer | |
| try: | |
| nltk.data.find("sentiment/vader_lexicon.zip") | |
| except LookupError: | |
| nltk.download("vader_lexicon", quiet=True) | |
| return SentimentIntensityAnalyzer() | |
| def split_sentences(text: str) -> List[str]: | |
| parts = re.split(r"(?<=[.!?])\s+", text.strip()) | |
| return [p.strip() for p in parts if p.strip()] | |
| def score_sentence(sentence: str) -> float: | |
| return snap_to_grid(_analyzer().polarity_scores(sentence)["compound"]) | |
| def compute_vader_sentiment(text: str) -> Tuple[List[str], List[float], float]: | |
| """Return (sentences, per-sentence sentiment on the 0.1 grid, overall).""" | |
| sentences = split_sentences(text) | |
| sentiments = [score_sentence(s) for s in sentences] | |
| overall = snap_to_grid(_analyzer().polarity_scores(text)["compound"]) | |
| return sentences, sentiments, overall | |
| def strip_sentiment_marker(text: str) -> str: | |
| """Drop a leading ``[0.3]`` style control token.""" | |
| return re.sub(r"^\s*\[[+-]?\d+(\.\d+)?\]\s*", "", text) | |
| def clean_generated_text(text: str) -> str: | |
| """Detokenisation cleanup for text decoded out of the MLM.""" | |
| cleaned = re.sub(r"\b(\w+)\s+##(\w+)", r"\1\2", text) | |
| cleaned = re.sub(r"<[^>]*>", "", cleaned) | |
| cleaned = re.sub(r"\[[+-]?\d+(\.\d+)?\]", " ", cleaned) | |
| cleaned = re.sub(r"\s+", " ", cleaned).strip() | |
| parts = [p.strip() for p in re.split(r"\s{2,}", cleaned) if p.strip()] | |
| if not parts: | |
| return cleaned | |
| result_parts = [] | |
| for p in parts: | |
| if p and p[-1] not in ".!?": | |
| p += "." | |
| result_parts.append(p) | |
| out = " ".join(result_parts) | |
| out = re.sub(r"\s+", " ", out).strip() | |
| out = re.sub(r"\s+([,.;:!?])", r"\1", out) | |
| out = re.sub(r"\s*'\s*", "'", out) | |
| out = re.sub(r"\.\.+", ".", out) | |
| out = re.sub(r'"', "", out) | |
| return out | |
| def choose_random_sentiment(exclude: float | None = None, rng=None) -> float: | |
| """Pick a grid value, optionally excluding the current one.""" | |
| import random as _random | |
| rng = rng or _random | |
| options: Sequence[float] = SENTIMENT_GRID | |
| if exclude is not None: | |
| exclude = snap_to_grid(exclude) | |
| options = [v for v in SENTIMENT_GRID if v != exclude] | |
| return float(rng.choice(list(options))) | |