Instructions to use pravz/slm_v1 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use pravz/slm_v1 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="pravz/slm_v1") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("pravz/slm_v1") model = AutoModelForCausalLM.from_pretrained("pravz/slm_v1", device_map="auto") messages = [ {"role": "user", "content": "Who are you?"}, ] inputs = tokenizer.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=40) print(tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use pravz/slm_v1 with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "pravz/slm_v1" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "pravz/slm_v1", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/pravz/slm_v1
- SGLang
How to use pravz/slm_v1 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 "pravz/slm_v1" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "pravz/slm_v1", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'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 "pravz/slm_v1" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "pravz/slm_v1", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use pravz/slm_v1 with Docker Model Runner:
docker model run hf.co/pravz/slm_v1
tradebot-slm-v1
A 1.5B model that reads an Indian corporate filing (NSE/BSE) and emits structured JSON โ event type, materiality, extracted amounts, and a prediction of whether and how the stock moves:
{"event_type": "ORDER_WIN", "materiality": "HIGH", "surprise": "MEDIUM",
"facts": {"amount_inr_cr": 412.0, "amount_basis": "NEW_ORDER",
"amount_to_mcap": 0.041},
"direction": "UP", "mover": true, "shape": "IMMEDIATE",
"price_path": [3, 8, 14, 17, 19, 21, 22, 22, 23, 24, 24, 25, 25, 26, 26, 31, 28],
"volume_path": [9.1, 6.4, 4.8, 3.9, 3.3, 2.9, 2.6, 2.4, 2.2, 2.1, 2.0, 1.9, 1.8, 1.8, 1.7, 1.4, 1.1]}
price_path is the market-adjusted return in tenths of a percent at
t1โฆt15, t30, t60. volume_path is the multiple of that symbol's pre-news
1-minute volume norm. Vocabularies: event_type โ {ORDER_WIN, RESULTS, MA,
DIVIDEND, BUYBACK, BOARD_MEETING, MGMT_CHANGE, FUNDRAISE, REGULATORY, PRESS,
INVESTOR_MEET, RATING, SHAREHOLDER, TRADING_WINDOW, OTHER}; materiality โ
{HIGH, MEDIUM, LOW, UNKNOWN}; surprise โ {HIGH, MEDIUM, LOW, NONE};
direction โ {UP, DOWN, FLAT}; shape โ {IMMEDIATE, DELAYED, FADE, FLAT};
amount_basis โ {NEW_ORDER, RENEWAL, OTHER, NONE}.
There is deliberately no confidence field โ the targets are measured outcomes, and nothing in the corpus supervises a calibrated self-estimate.
Code: github.com/thenameispravardhan/market-proof โ corpus construction, frozen baselines, evaluation, a stdlib OpenAI-compatible server (
serve_slm.py) and the live trading system this model plugs into. Note that the schema above is not a generic chat format: consuming it in an application needs a mapping layer (app/analyzer/slm_adapter.pyis ours).
What makes it unusual: it is supervised by measured market reaction, not by another LLM's sentiment labels. FinBERT, FinGPT and FinMA are all trained on human- or LLM-assigned sentiment. This one's targets are what the price actually did in the 15 minutes after the filing was published, market-adjusted against NIFTY 50.
Results, stated honestly
Head-to-head against DeepSeek on the same 600 filings, neither model having seen them:
| tradebot-slm-v1 | DeepSeek | always-predict-FLAT | |
|---|---|---|---|
| direction accuracy | 0.5733 | 0.5617 | 0.5950 |
| balanced accuracy | 0.3317 | 0.3236 | 0.3333 |
| mover ROC-AUC | 0.5071 | 0.4234 | 0.500 |
Two things are true at once and both belong in the summary:
- It beats DeepSeek on every metric, and DeepSeek's confidence is anti-predictive (0.4234, below the 0.500 coin flip) โ independently reproducing an inversion measured on 17,298 filings in production.
- Both lose to a constant. They fail the same way: DeepSeek answers HOLD 94.0% of the time, this model answers FLAT 94.2%. Beating a model that is worse than a coin flip proves very little.
As a feature extractor
Mean-pooled hidden states, fed to the same gradient-boosting head, on the frozen chronological test split (n=17,723):
| representation | alone | + market features | PR-AUC |
|---|---|---|---|
| TF-IDF + SVD(256) | 0.7014 | 0.7649 | 0.3956 |
| this model's embedding | 0.6578 | 0.7621 | 0.3977 |
| market features only | โ | 0.7513 | 0.3718 |
Paired bootstrap, 2,000 resamples:
| comparison | ฮ ROC-AUC | 95% CI | verdict |
|---|---|---|---|
| fine-tune + market vs market | +0.0108 | [+0.0074, +0.0145] | significant |
| TF-IDF + market vs market | +0.0136 | [+0.0095, +0.0177] | significant |
| TF-IDF vs fine-tune | +0.0028 | [โ0.0001, +0.0057] | spans 0 โ indistinguishable |
A $33 fine-tune matched TF-IDF + SVD, which costs ten minutes of laptop CPU. Not beaten, not lost โ matched. Text does carry signal beyond market state (both clear the baseline with intervals well clear of zero), but this model is not a better way to extract it than a bag of words.
Why, in hindsight: the training objective is next-token prediction over a JSON schema. That optimises format compliance โ eval loss fell 74% โ and nothing in it asks the hidden states to encode what makes a filing move.
What is untested
The generative output โ event classification, amount extraction, evidence spans โ has not been evaluated. That is the part with no cheap substitute, and the honest next measurement.
Do not quote raw accuracy
Direction at ยฑ3% reads 0.9638. That is the base rate. 96.4% of filings do
not move 3%; a model that says FLAT every time scores 0.9643. Balanced
accuracy is the honest column and it says 0.3333 โ chance. Direction is not
learnable at ยฑ1/2/3% on this data; mover is the only learnable target.
Training
| base | Qwen/Qwen2.5-1.5B-Instruct (Apache 2.0) |
| method | full fine-tune, no LoRA |
| data | 146,500 NSE filings, chronological split (train โค 2026-04-04) |
| epochs / steps | 1 / 2,290 |
| lr, schedule | 1e-5, cosine, 3% warmup |
| batch | 1 ร 64 accumulation, seq 2,048 |
| optimizer | 8-bit AdamW |
| hardware | 1ร A10G (g5.2xlarge), ~19 h, ~$33 |
| eval loss / ppl | 0.4102 / 1.507 (eval below train throughout) |
| checkpoint | 2,000 โ picked on validation, not on being last |
Steps 1,000 โ 2,250 improved eval loss by 0.0018 for ~11 hours and ~$19. If you retrain, budget one epoch and expect the useful learning in the first third.
The corpus was built from 243,533 filings with measured outcomes, extracted from source PDFs at 98.0% coverage (OCR pass included). Near-duplicates were removed per (template, symbol) โ 9.3% of Indian filings are near-copies of each other, and training on the same cover letter repeatedly teaches the cover letter.
Usage
The prompt format is part of the weights. All 146,500 training examples used the exact system prompt and user layout below. Improvise on it and the model is off-distribution โ you get worse output and the fine-tune is wasted.
from transformers import AutoModelForCausalLM, AutoTokenizer
tok = AutoTokenizer.from_pretrained("pravz/slm_v1")
model = AutoModelForCausalLM.from_pretrained("pravz/slm_v1", dtype="auto")
SYSTEM = (
"You are a financial analyst specialised in Indian NSE/BSE corporate "
"filings. Read the filing, extract the material facts, and reason about "
"the likely market reaction. Return only the requested JSON. Never use "
"information from after the filing timestamp."
)
user = f"""SYMBOL: {symbol}
FILED: {filed_at}
HEADLINE: {headline}
FILING:
{filing_text}"""
ids = tok.apply_chat_template(
[{"role": "system", "content": SYSTEM}, {"role": "user", "content": user}],
return_tensors="pt", add_generation_prompt=True,
)
print(tok.decode(model.generate(ids, max_new_tokens=400)[0][ids.shape[-1]:],
skip_special_tokens=True))
Training prompts also carried a MARKET CONTEXT block (last trade before the
filing, pre-news volume ratio, market-cap tier, session). It is optional โ
omit the block entirely rather than filling it with placeholder numbers.
Or serve it behind an OpenAI-compatible endpoint: vllm serve pravz/slm_v1
on Linux+GPU, or the CPU-friendly, stdlib-only serve_slm.py in the repo
below, which runs anywhere transformers runs.
Speed: 4 tok/s on a CPU laptop in bf16 (36 s for one filing). Use a GPU
for anything interactive.
Intended use and limits
Research and education. Not investment advice. It was trained on 2025โ2026 Indian filings and will not transfer to other markets, other document types, or other time periods without re-measurement. Do not put it in front of money โ the results above say it does not beat a bag of words at the one task it was trained for.
Repository, dataset construction, baselines and evaluation code: https://github.com/thenameispravardhan/market-proof
- Downloads last month
- 731