Spaces:
Runtime error
Runtime error
Download main_old1.py from WildOjisan/qwen2_5_1_5b_instruct_basic_test: direct link, hf CLI and curl.
- Browser
- Download file 4.03 kB
-
https://huggingface.co/spaces/WildOjisan/qwen2_5_1_5b_instruct_basic_test/resolve/main/main_old1.py
- Command line
-
hf download hf://spaces/WildOjisan/qwen2_5_1_5b_instruct_basic_test/main_old1.py
-
curl -L -o main_old1.py https://huggingface.co/spaces/WildOjisan/qwen2_5_1_5b_instruct_basic_test/resolve/main/main_old1.py
4.03 kB
| import os | |
| # ✅ Hugging Face 캐시/토큰 경로를 쓰기 가능한 위치로 지정 (Spaces에서는 /data가 안전) | |
| os.environ["HF_HOME"] = "/data" | |
| os.environ["TRANSFORMERS_CACHE"] = "/data/transformers" | |
| os.environ["HF_HUB_CACHE"] = "/data/hub" | |
| os.environ.setdefault("TOKENIZERS_PARALLELISM", "false") | |
| os.environ.setdefault("PYTORCH_FORCE_MPS_FALLBACK", "1") | |
| import threading | |
| from typing import List, Optional, Dict, Any, Iterator | |
| import torch | |
| from fastapi import FastAPI, Body | |
| from fastapi.responses import StreamingResponse, JSONResponse | |
| from pydantic import BaseModel, Field | |
| from transformers import ( | |
| AutoTokenizer, | |
| AutoModelForCausalLM, | |
| TextIteratorStreamer, | |
| ) | |
| MODEL_ID = "unsloth/Qwen2.5-1.5B-Instruct" # :contentReference[oaicite:3]{index=3} | |
| try: | |
| torch.set_num_threads(max(1, os.cpu_count() or 1)) | |
| except Exception: | |
| pass | |
| # ---- 전역 모델/토크나이저 로드 ---- | |
| print(f"[BOOT] Loading {MODEL_ID} on CPU(float32)...") | |
| tokenizer = AutoTokenizer.from_pretrained( | |
| MODEL_ID, | |
| use_fast=False, | |
| trust_remote_code=True, | |
| ) | |
| model = AutoModelForCausalLM.from_pretrained( | |
| MODEL_ID, | |
| torch_dtype=torch.float32, | |
| device_map="cpu", | |
| low_cpu_mem_usage=True, # accelerate 필요 (요건 requirements에 반영됨) :contentReference[oaicite:4]{index=4} | |
| trust_remote_code=True, | |
| ) | |
| model.eval() | |
| # ---- API 모델 ---- | |
| class ChatMessage(BaseModel): | |
| role: str = Field(..., description="system | user | assistant") | |
| content: str | |
| class ChatRequest(BaseModel): | |
| messages: List[ChatMessage] | |
| max_new_tokens: int = 256 | |
| temperature: float = 0.7 | |
| top_p: float = 0.95 | |
| repetition_penalty: float = 1.1 | |
| class ChatResponse(BaseModel): | |
| text: str | |
| app = FastAPI(title="Qwen2.5-1.5B CPU API") | |
| def health(): | |
| return {"status": "ok", "model": MODEL_ID} | |
| def build_prompt(messages: List[Dict[str, str]]) -> str: | |
| # Qwen 계열 권장: chat 템플릿 사용(업로드 스크립트와 동일 컨셉) :contentReference[oaicite:5]{index=5} | |
| return tokenizer.apply_chat_template( | |
| [{"role": m["role"], "content": m["content"]} for m in messages], | |
| tokenize=False, | |
| add_generation_prompt=True, | |
| ) | |
| def chat(req: ChatRequest): | |
| prompt = build_prompt([m.dict() for m in req.messages]) | |
| inputs = tokenizer(prompt, return_tensors="pt") | |
| with torch.no_grad(): | |
| output_ids = model.generate( | |
| **{k: v.to("cpu") for k, v in inputs.items()}, | |
| max_new_tokens=req.max_new_tokens, | |
| do_sample=True, | |
| temperature=req.temperature, | |
| top_p=req.top_p, | |
| repetition_penalty=req.repetition_penalty, | |
| eos_token_id=tokenizer.eos_token_id, | |
| pad_token_id=tokenizer.eos_token_id, | |
| ) | |
| text = tokenizer.decode(output_ids[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True) | |
| return ChatResponse(text=text) | |
| def stream_generate(req: ChatRequest) -> Iterator[str]: | |
| prompt = build_prompt([m.dict() for m in req.messages]) | |
| inputs = tokenizer(prompt, return_tensors="pt") | |
| streamer = TextIteratorStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True) | |
| gen_kwargs = dict( | |
| **{k: v.to("cpu") for k, v in inputs.items()}, | |
| max_new_tokens=req.max_new_tokens, | |
| do_sample=True, | |
| temperature=req.temperature, | |
| top_p=req.top_p, | |
| repetition_penalty=req.repetition_penalty, | |
| eos_token_id=tokenizer.eos_token_id, | |
| pad_token_id=tokenizer.eos_token_id, | |
| streamer=streamer, | |
| ) | |
| thread = threading.Thread(target=model.generate, kwargs=gen_kwargs) | |
| thread.start() | |
| # NDJSON(한 줄에 { "delta": "..." }) 형태로 전송 | |
| for token_text in streamer: | |
| yield f'{{"delta": {token_text.__repr__()}}}\n' | |
| def chat_stream(req: ChatRequest = Body(...)): | |
| return StreamingResponse( | |
| stream_generate(req), | |
| media_type="application/x-ndjson", | |
| ) | |