RexTRO111's picture
Upload 3 files
e6cd8c3 verified
Raw
History Blame Contribute Delete
5.26 kB
import modal
APP_NAME = "pythia-410m-dolly-test"
VOLUME_NAME = "pythia-410m-dolly-output"
BASE_MODEL = "EleutherAI/pythia-410m"
VOLUME_ROOT = "/data"
ADAPTER_DIR = (
f"{VOLUME_ROOT}/outputs/"
"pythia-410m-dolly-lora/final-adapter"
)
CACHE_DIR = f"{VOLUME_ROOT}/cache/huggingface"
app = modal.App(APP_NAME)
volume = modal.Volume.from_name(
VOLUME_NAME,
create_if_missing=False,
)
image = (
modal.Image.debian_slim(python_version="3.11")
.pip_install(
"torch==2.7.1",
"transformers==4.53.2",
"peft==0.16.0",
"accelerate==1.8.1",
"safetensors==0.5.3",
"sentencepiece==0.2.0",
)
.env(
{
"HF_HOME": CACHE_DIR,
"TRANSFORMERS_CACHE": CACHE_DIR,
"TOKENIZERS_PARALLELISM": "false",
}
)
)
@app.function(
image=image,
gpu="T4",
cpu=2.0,
memory=8192,
timeout=15 * 60,
volumes={
VOLUME_ROOT: volume.with_mount_options(read_only=True),
},
)
def generate(
instruction: str,
context: str = "",
max_new_tokens: int = 200,
temperature: float = 0.7,
top_p: float = 0.9,
top_k: int = 40,
repetition_penalty: float = 1.1,
seed: int = 3407,
) -> str:
import os
import torch
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer
if not os.path.isdir(ADAPTER_DIR):
raise FileNotFoundError(
f"Adapter directory was not found: {ADAPTER_DIR}"
)
required_files = [
"adapter_config.json",
"adapter_model.safetensors",
]
for filename in required_files:
path = os.path.join(ADAPTER_DIR, filename)
if not os.path.isfile(path):
raise FileNotFoundError(
f"Required adapter file was not found: {path}"
)
if not torch.cuda.is_available():
raise RuntimeError("CUDA GPU was not detected.")
torch.manual_seed(seed)
torch.cuda.manual_seed_all(seed)
print(f"GPU: {torch.cuda.get_device_name(0)}")
print(f"Base model: {BASE_MODEL}")
print(f"Adapter: {ADAPTER_DIR}")
# The tokenizer was saved with the final LoRA adapter.
tokenizer = AutoTokenizer.from_pretrained(
ADAPTER_DIR,
cache_dir=CACHE_DIR,
use_fast=True,
)
if tokenizer.pad_token_id is None:
tokenizer.pad_token = tokenizer.eos_token
tokenizer.padding_side = "left"
base_model = AutoModelForCausalLM.from_pretrained(
BASE_MODEL,
cache_dir=CACHE_DIR,
torch_dtype=torch.float16,
low_cpu_mem_usage=True,
)
model = PeftModel.from_pretrained(
base_model,
ADAPTER_DIR,
is_trainable=False,
)
model = model.to("cuda")
model.eval()
clean_instruction = instruction.strip()
clean_context = context.strip()
if clean_context:
prompt = (
"### Instruction:\n"
f"{clean_instruction}\n\n"
"### Context:\n"
f"{clean_context}\n\n"
"### Response:\n"
)
else:
prompt = (
"### Instruction:\n"
f"{clean_instruction}\n\n"
"### Response:\n"
)
inputs = tokenizer(
prompt,
return_tensors="pt",
truncation=True,
max_length=768,
).to("cuda")
input_length = inputs["input_ids"].shape[1]
generation_kwargs = {
"max_new_tokens": max_new_tokens,
"pad_token_id": tokenizer.pad_token_id,
"eos_token_id": tokenizer.eos_token_id,
"repetition_penalty": repetition_penalty,
"use_cache": True,
}
# Temperature 0 means greedy decoding.
if temperature > 0:
generation_kwargs.update(
{
"do_sample": True,
"temperature": temperature,
"top_p": top_p,
"top_k": top_k,
}
)
else:
generation_kwargs["do_sample"] = False
with torch.inference_mode():
output_ids = model.generate(
**inputs,
**generation_kwargs,
)
# Decode only tokens generated after the prompt.
generated_ids = output_ids[0, input_length:]
response = tokenizer.decode(
generated_ids,
skip_special_tokens=True,
).strip()
return response
@app.local_entrypoint()
def main(
prompt: str = "Explain artificial intelligence in simple terms.",
context: str = "",
max_new_tokens: int = 200,
temperature: float = 0.7,
top_p: float = 0.9,
top_k: int = 40,
repetition_penalty: float = 1.1,
seed: int = 3407,
):
response = generate.remote(
instruction=prompt,
context=context,
max_new_tokens=max_new_tokens,
temperature=temperature,
top_p=top_p,
top_k=top_k,
repetition_penalty=repetition_penalty,
seed=seed,
)
print("\n" + "=" * 72)
print("PROMPT")
print("=" * 72)
print(prompt)
if context:
print("\n" + "=" * 72)
print("CONTEXT")
print("=" * 72)
print(context)
print("\n" + "=" * 72)
print("MODEL RESPONSE")
print("=" * 72)
print(response)
print("=" * 72)