File size: 4,563 Bytes
d589fb4 86a1e30 d589fb4 5720afb d589fb4 86a1e30 28d21d5 d589fb4 40d1c74 86a1e30 d589fb4 40d1c74 d589fb4 28d21d5 d589fb4 40d1c74 d589fb4 40d1c74 d589fb4 40d1c74 d589fb4 28d21d5 d589fb4 28d21d5 40d1c74 28d21d5 d589fb4 28d21d5 d589fb4 28d21d5 86a1e30 d589fb4 40d1c74 d589fb4 28d21d5 40d1c74 28d21d5 86a1e30 40d1c74 86a1e30 40d1c74 37c4030 28d21d5 37c4030 | 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 | import os
import json
from typing import List, Optional
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from pydantic import BaseModel
from huggingface_hub import hf_hub_download
import gradio as gr
import uvicorn
import spaces
import subprocess
import sys
# --- Instalação do llama-cpp-python via wheel (compatível com o ambiente do HF) ---
# Este comando instala a biblioteca a partir de um pacote binário pré-compilado.
# É uma alternativa robusta para evitar erros de compilação no ambiente do Space.
subprocess.check_call([
sys.executable, "-m", "pip", "install", "--no-cache-dir",
"https://huggingface.co/Luigi/llama-cpp-python-wheels-hf-spaces-free-cpu/resolve/main/llama_cpp_python-0.3.22-cp310-cp310-linux_x86_64.whl"
])
# Agora que o wheel foi instalado, podemos importar a biblioteca com segurança.
from llama_cpp import Llama
# --- Modelo ---
MODEL_REPO = "bartowski/Dolphin3.0-Llama3.1-8B-GGUF"
MODEL_FILE = "Dolphin3.0-Llama3.1-8B-Q4_K_M.gguf"
N_CTX = 4096
N_THREADS = 4
llm = None
def load_model():
global llm
if llm is None:
print(f"Baixando/carregando modelo: {MODEL_REPO}/{MODEL_FILE}")
model_path = hf_hub_download(repo_id=MODEL_REPO, filename=MODEL_FILE)
llm = Llama(
model_path=model_path,
n_ctx=N_CTX,
n_threads=N_THREADS,
n_gpu_layers=-1, # Tenta usar a GPU (se disponível)
verbose=False,
)
print("Modelo carregado com sucesso.")
return llm
# --- Schemas OpenAI ---
class ChatMessage(BaseModel):
role: str
content: str
class ChatCompletionRequest(BaseModel):
model: str = "dolphin-llama3.1-8b"
messages: List[ChatMessage]
temperature: float = 0.7
max_tokens: Optional[int] = 512
stream: bool = False
# --- FastAPI ---
api = FastAPI()
@api.get("/v1/models")
async def list_models():
return {
"object": "list",
"data": [
{
"id": "dolphin-llama3.1-8b",
"object": "model",
"created": 1700000000,
"owned_by": "local",
}
],
}
@spaces.GPU # <-- Esta linha garante que a GPU seja alocada para a inferência
def generate_response(prompt: str, max_tokens: int, temperature: float):
model = load_model()
output = model(prompt, max_tokens=max_tokens, temperature=temperature, stream=False)
return output["choices"][0]["text"]
@api.post("/v1/chat/completions")
async def chat_completions(req: ChatCompletionRequest):
# Formata o prompt para o modelo Dolphin (formato ChatML)
prompt = ""
for msg in req.messages:
if msg.role == "system":
prompt += f"<|im_start|>system\n{msg.content}<|im_end|>\n"
elif msg.role == "user":
prompt += f"<|im_start|>user\n{msg.content}<|im_end|>\n"
elif msg.role == "assistant":
prompt += f"<|im_start|>assistant\n{msg.content}<|im_end|>\n"
prompt += "<|im_start|>assistant\n"
# --- Modo de streaming ---
if req.stream:
async def stream_generator():
model = load_model()
output = model(prompt, max_tokens=req.max_tokens, temperature=req.temperature, stream=True)
for chunk in output:
token = chunk["choices"][0]["text"]
data = {
"id": "chatcmpl-local",
"object": "chat.completion.chunk",
"choices": [{"delta": {"content": token}, "index": 0, "finish_reason": None}],
}
yield f"data: {json.dumps(data)}\n\n"
yield "data: [DONE]\n\n"
return StreamingResponse(stream_generator(), media_type="text/event-stream")
# --- Modo normal ---
text = generate_response(prompt, req.max_tokens, req.temperature)
return {
"id": "chatcmpl-local",
"object": "chat.completion",
"created": 1700000000,
"model": req.model,
"choices": [{"index": 0, "message": {"role": "assistant", "content": text}, "finish_reason": "stop"}],
"usage": {"prompt_tokens": 0, "completion_tokens": 0, "total_tokens": 0},
}
# --- Gradio (Interface web + API) ---
def dummy(x):
return x
demo = gr.Interface(fn=dummy, inputs="text", outputs="text")
# --- Monta o Gradio dentro do FastAPI ---
app = gr.mount_gradio_app(api, demo, path="/ui")
# --- Rodar (o Hugging Face inicia via `python app.py`) ---
if __name__ == "__main__":
load_model()
uvicorn.run(app, host="0.0.0.0", port=7860) |