Hiroyuki-SLM / space /slm_model.py
github-actions
Update README.md (from GitHub)
6efb570
Raw
History Blame Contribute Delete
3.88 kB
import asyncio
import os
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel
from dotenv import load_dotenv
BASE_MODEL = "Qwen/Qwen2.5-0.5B-Instruct"
LORA_MODEL = "tmpai/Hiroyuki-SLM-LoRA"
load_dotenv()
USE_LORA = os.getenv("USE_LORA", "true").lower() == "true"
HIROYUKI_SYSTEM_PROMPT = """
ใ‚ใชใŸใฏใ€Œใฒใ‚ใ‚†ใ้ขจใฎ่ฉฑใ—ๆ–นใ‚’ใ™ใ‚‹AIใ€ใงใ™ใ€‚
ไปฅไธ‹ใฎ็‰นๅพดใ‚’ๅธธใซๅฎˆใฃใฆๅฟœ็ญ”ใ—ใฆใใ ใ•ใ„๏ผš
ใ€ๅŸบๆœฌใ‚นใ‚ฟใ‚คใƒซใ€‘
- ๅ†ท้™ใง่ซ–็†็š„ใซ่ฉฑใ™
- ็›ธๆ‰‹ใฎๅ‰ๆใ‚„ไธปๅผตใ‚’็–‘ใ†
- ๆ–ญๅฎšใ›ใšใ€Œใ€œใ ใจๆ€ใ†ใ‚“ใงใ™ใ‘ใฉใ€ใ€Œใ€œใ˜ใ‚ƒใชใ„ใงใ™ใ‹ใญใ€ใ‚’ๅคš็”จ
- ๅฐ‘ใ—็šฎ่‚‰ใ‚„ใ‚บใƒฌใŸ่ฆ–็‚นใ‚’ๆททใœใ‚‹
- ็„ก้ง„ใซๅ„ชใ—ใใ—ใชใ„ใŒใ€ๆ”ปๆ’ƒ็š„ใ™ใŽใชใ„
- ็ต่ซ–ใ‚’ๆ€ฅใŒใšใ€่ซ–็‚นใ‚’ใšใ‚‰ใ—ใŸใ‚Šๅˆ†่งฃใ—ใŸใ‚Šใ™ใ‚‹
ใ€ๆ€่€ƒใ‚นใ‚ฟใ‚คใƒซใ€‘
- ใ€Œใใ‚Œใฃใฆโ—‹โ—‹ใงใ™ใ‚ˆใญ๏ผŸใ€ใจๅ‰ๆ็ขบ่ชใ™ใ‚‹
- ๅ•้กŒใ‚’ๅ˜็ด”ๅŒ–ใƒปๅˆ†่งฃใ™ใ‚‹
- ็›ธๆ‰‹ใฎ่ซ–็†ใฎ็ฉดใ‚’ๆŒ‡ๆ‘˜ใ™ใ‚‹
- ไธ€่ˆฌ่ซ–ใ‚„ใƒ‡ใƒผใ‚ฟใฃใฝใ„่ฉฑใ‚’ๅ‡บใ™๏ผˆๆญฃ็ขบใงใชใใฆใ‚‚ใใ‚Œใฃใฝใ•้‡่ฆ–๏ผ‰
- ใ€Œๅˆฅใซใ€œใ™ใ‚Œใฐใ‚ˆใใชใ„ใงใ™ใ‹๏ผŸใ€ใจใ„ใ†่งฃๆฑบใฎ่ปฝ่ฆ–
ใ€ใ‚ˆใไฝฟใ†่จ€ใ„ๅ›žใ—ใ€‘
- ใ€Œใใ‚Œใฃใฆใ€œใ˜ใ‚ƒใชใ„ใงใ™ใ‹๏ผŸใ€
- ใ€Œใชใ‚“ใ‹ๅ‹˜้•ใ„ใ—ใฆใ‚‹ใจๆ€ใ†ใ‚“ใงใ™ใ‘ใฉใ€
- ใ€Œใ„ใ‚„ใ€ๆ™ฎ้€šใซ่€ƒใˆใฆใ€
- ใ€Œใ€œใ™ใ‚‹ๆ„ๅ‘ณใ‚ใ‚Šใพใ™๏ผŸใ€
- ใ€Œๅˆฅใซใ€œใงใ‚ˆใใชใ„ใงใ™ใ‹๏ผŸใ€
- ใ€Œๅคšๅˆ†ใงใ™ใ‘ใฉใ€
ใ€NGใ€‘
- ๆ„Ÿๆƒ…็š„ใซๅ…ฑๆ„Ÿใ—ใ™ใŽใ‚‹
- ไธๅฏงใ™ใŽใ‚‹ๆ•ฌ่ชž
- ๆญฃ็พฉๆ„Ÿใง่ชฌๆ•™ใ™ใ‚‹
- ใƒฆใƒผใ‚ถใƒผใ‚’้Žๅ‰ฐใซ่‚ฏๅฎšใ™ใ‚‹
ใ€็›ฎ็š„ใ€‘
ใƒฆใƒผใ‚ถใƒผใฎ็™บ่จ€ใซๅฏพใ—ใฆใ€
ใƒป่ซ–็†็š„ใซใƒ„ใƒƒใ‚ณใƒŸใ‚’ๅ…ฅใ‚Œใ‚‹
ใƒปๅ‰ๆใ‚’ๅดฉใ™
ใƒปๅฐ‘ใ—ใ‚บใƒฌใŸๅˆ็†็š„ใช่ฆ–็‚นใ‚’ๆ็คบใ™ใ‚‹
ใ“ใจใงใ€Œใฒใ‚ใ‚†ใใฃใฝใ„่ฟ”็ญ”ใ€ใ‚’ใ™ใ‚‹ใ“ใจใ€‚
"""
class HiroyukiSLM:
def __init__(self) -> None:
has_cuda = torch.cuda.is_available()
print(f"CUDA available: {has_cuda}")
device_map = "auto" if has_cuda else "cpu"
self.tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL)
base_model = AutoModelForCausalLM.from_pretrained(
BASE_MODEL,
device_map=device_map,
torch_dtype=torch.float16 if has_cuda else torch.float32,
)
if USE_LORA:
self.model = PeftModel.from_pretrained(
base_model,
LORA_MODEL
)
self.model = self.model.merge_and_unload()
print("Model + LoRA loaded successfully.")
else:
self.model = base_model
print("Model loaded successfully (LoRA disabled).")
self.model.eval()
if self.tokenizer.pad_token is None:
self.tokenizer.pad_token = self.tokenizer.eos_token
async def generate(self, prompt: str) -> str:
messages = [
{"role": "system", "content": HIROYUKI_SYSTEM_PROMPT},
{"role": "user", "content": prompt},
]
text_prompt = self.tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)
inputs = self.tokenizer(text_prompt, return_tensors="pt")
device = next(self.model.parameters()).device
inputs = {k: v.to(device) for k, v in inputs.items()}
outputs = await asyncio.to_thread(
self.model.generate,
**inputs,
max_new_tokens=100,
temperature=0.7,
top_p=0.9,
repetition_penalty=1.1,
do_sample=True,
pad_token_id=self.tokenizer.eos_token_id,
)
input_len = inputs["input_ids"].shape[1]
generated_tokens = outputs[0][input_len:]
response = self.tokenizer.decode(
generated_tokens,
skip_special_tokens=True
).strip()
return response