Text Generation
PEFT
Safetensors
Transformers
Indonesian
Javanese
Sundanese
lora
qlora
sft
trl
unsloth
conversational
tool-use
indonesian
javanese
sundanese
gig-economy
ride-hailing
fairleap
Instructions to use fairleap-ai/fairleap-v1-clm-sahabatai-8b-adapter with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use fairleap-ai/fairleap-v1-clm-sahabatai-8b-adapter with PEFT:
from peft import PeftModel from transformers import AutoModelForCausalLM base_model = AutoModelForCausalLM.from_pretrained("GoToCompany/llama3-8b-cpt-sahabatai-v1-instruct") model = PeftModel.from_pretrained(base_model, "fairleap-ai/fairleap-v1-clm-sahabatai-8b-adapter") - Transformers
How to use fairleap-ai/fairleap-v1-clm-sahabatai-8b-adapter with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="fairleap-ai/fairleap-v1-clm-sahabatai-8b-adapter") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("fairleap-ai/fairleap-v1-clm-sahabatai-8b-adapter", device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use fairleap-ai/fairleap-v1-clm-sahabatai-8b-adapter with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "fairleap-ai/fairleap-v1-clm-sahabatai-8b-adapter" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "fairleap-ai/fairleap-v1-clm-sahabatai-8b-adapter", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/fairleap-ai/fairleap-v1-clm-sahabatai-8b-adapter
- SGLang
How to use fairleap-ai/fairleap-v1-clm-sahabatai-8b-adapter 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 "fairleap-ai/fairleap-v1-clm-sahabatai-8b-adapter" \ --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": "fairleap-ai/fairleap-v1-clm-sahabatai-8b-adapter", "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 "fairleap-ai/fairleap-v1-clm-sahabatai-8b-adapter" \ --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": "fairleap-ai/fairleap-v1-clm-sahabatai-8b-adapter", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Unsloth Desktop
- Docker Model Runner
How to use fairleap-ai/fairleap-v1-clm-sahabatai-8b-adapter with Docker Model Runner:
docker model run hf.co/fairleap-ai/fairleap-v1-clm-sahabatai-8b-adapter
File size: 5,290 Bytes
ab4499e | 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 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | """Validate the Llama-3 tool template against the real corpus, off-GPU.
Everything here runs on jinja2 + tokenizers alone -- no torch, no VM -- so the
template is proven before any GPU time is spent. It checks the two things that
fail silently rather than loudly:
* tool calls and tool schemas survive rendering (the stock Sahabat-AI
template drops both, and an assistant tool-call turn has `content: ""`, so
the damage looks like an ordinary empty reply);
* response-only masking covers exactly the assistant turns. A tool result
rendered under a header the instruction delimiter does not match would sit
inside the loss and teach the model to write its own forecasts.
python3 training/check_template.py --data train.parquet \
--tokenizer tokenizer.json
"""
import argparse
import json
import statistics
from pathlib import Path
import jinja2.ext
import pyarrow.parquet as pq
from jinja2.sandbox import ImmutableSandboxedEnvironment
TEMPLATE = Path(__file__).resolve().parent / "llama3_tools.jinja"
BOS = "<|begin_of_text|>"
INSTRUCTION_PART = "<|start_header_id|>user<|end_header_id|>\n\n"
RESPONSE_PART = "<|start_header_id|>assistant<|end_header_id|>\n\n"
def build_env():
"""Reproduce transformers' template environment closely enough to trust."""
env = ImmutableSandboxedEnvironment(
trim_blocks=True, lstrip_blocks=True, extensions=[jinja2.ext.loopcontrols])
env.filters["tojson"] = lambda x, **kw: json.dumps(
x, ensure_ascii=kw.get("ensure_ascii", False), indent=kw.get("indent"))
env.globals["raise_exception"] = lambda m: (_ for _ in ()).throw(Exception(m))
return env
def hydrate(row):
messages = []
for message in row["messages"]:
clean = {k: v for k, v in message.items() if v is not None}
if "tool_calls" in clean:
clean["tool_calls"] = json.loads(clean["tool_calls"])
messages.append(clean)
tools = row.get("tools")
return messages, (json.loads(tools) if tools else None)
def trained_spans(text):
"""The character spans train_on_responses_only would keep in the loss.
unsloth trains from each response delimiter to the next *instruction*
delimiter, or to the end. Working in characters rather than token ids is
equivalent here and keeps the check tokenizer-free.
"""
spans, cursor = [], 0
while (start := text.find(RESPONSE_PART, cursor)) != -1:
start += len(RESPONSE_PART)
stop = text.find(INSTRUCTION_PART, start)
stop = len(text) if stop == -1 else stop
spans.append((start, stop))
cursor = stop
return spans
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--data", required=True,
help="train.parquet from prepare_data.py")
parser.add_argument("--tokenizer", help="path to a tokenizer.json, for length stats")
parser.add_argument("--rows", type=int, default=4000)
args = parser.parse_args()
template = build_env().from_string(TEMPLATE.read_text(encoding="utf-8"))
rows = pq.read_table(args.data).slice(0, args.rows).to_pylist()
calls = schemas = leaked = empty_mask = 0
tool_rows = 0
lengths = []
tokenizer = None
if args.tokenizer:
from tokenizers import Tokenizer
tokenizer = Tokenizer.from_file(args.tokenizer)
for row in rows:
messages, tools = hydrate(row)
text = template.render(messages=messages, tools=tools, bos_token=BOS,
add_generation_prompt=False)
spans = trained_spans(text)
if not spans:
empty_mask += 1
trained = "".join(text[a:b] for a, b in spans)
# A tool result inside the trained span is the failure this exists for.
leaked += trained.count("<tool_response>")
for message in messages:
for call in message.get("tool_calls") or []:
tool_rows += 1
needle = f'{{"name": "{call["function"]["name"]}", "parameters": '
calls += needle in text
# ...and the call itself MUST be trained on, or the model never
# learns to emit one.
calls -= needle not in trained
if tools:
schemas += all(t["function"]["description"][:40] in text for t in tools)
if tokenizer:
lengths.append(len(tokenizer.encode(text, add_special_tokens=False).ids))
print(f"rows {len(rows)}")
print(f"tool calls {calls}/{tool_rows} rendered and inside the loss")
print(f"tool schemas {schemas} conversations carry the offered schema")
print(f"tool results leaked {leaked} (must be 0)")
print(f"empty label masks {empty_mask} (must be 0)")
if lengths:
lengths.sort()
n = len(lengths)
print(f"tokens mean={statistics.mean(lengths):.0f} "
f"p50={lengths[n // 2]} p90={lengths[int(n * .9)]} "
f"p99={lengths[int(n * .99)]} max={lengths[-1]} "
f"over_4096={sum(1 for x in lengths if x > 4096)}")
if leaked or empty_mask or calls != tool_rows:
raise SystemExit("template check FAILED")
print("template check OK")
if __name__ == "__main__":
main()
|