File size: 3,611 Bytes
f0f212a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f1dc31f
 
f0f212a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1b7e43f
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
import wget
import os
import asyncio
from fastapi import FastAPI
from pydantic import BaseModel
import executorch
import uvicorn

# Definir los parámetros de la solicitud utilizando Pydantic
class Request(BaseModel):
    # Valores por defecto para las rutas de los archivos
    model_path: str = "Llama-3.2-1B-Instruct-SpinQuant_INT4_EO8.pte"
    tokenizer_path: str = "tokenizer.model"
    
    # Valores por defecto para la temperatura y longitud de secuencia
    prompt: str
    temperature: float = 0.7
    seq_len: int = 256

# Crear una instancia de FastAPI
app = FastAPI()

# Cargar el modelo y el tokenizer globalmente para evitar recargarlo en cada solicitud
model = None
tokenizer = None

# Función para descargar el modelo y el tokenizer en la misma carpeta del código (ahora es asíncrona)
async def download_files(model_url: str, tokenizer_url: str, model_path: str, tokenizer_path: str):
    # Verificar si el archivo ya existe, si no, descargarlo
    if not os.path.exists(model_path):
        print(f"Descargando el modelo desde: {model_url}")
        # Usamos wget de manera asíncrona
        await asyncio.to_thread(wget.download, model_url, model_path)

    if not os.path.exists(tokenizer_path):
        print(f"Descargando el tokenizer desde: {tokenizer_url}")
        # Usamos wget de manera asíncrona
        await asyncio.to_thread(wget.download, tokenizer_url, tokenizer_path)

# Cargar el modelo y el tokenizer (se hace una vez al inicio) (ahora es asíncrona)
async def load_model(request: Request):
    global model, tokenizer
    
    # Si ya están cargados, no cargamos de nuevo
    if model is not None and tokenizer is not None:
        print("Modelo y tokenizer ya están cargados en la memoria.")
        return
    
    # URLs de los archivos a descargar
    model_url = "https://huggingface.co/executorch-community/Llama-3.2-1B-Instruct-SpinQuant_INT4_EO8-ET/resolve/main/Llama-3.2-1B-Instruct-SpinQuant_INT4_EO8.pte"
    tokenizer_url = "https://huggingface.co/executorch-community/Llama-3.2-1B-Instruct-SpinQuant_INT4_EO8-ET/resolve/main/tokenizer.model"
    
    # Obtener la ruta del directorio actual
    current_dir = os.path.dirname(os.path.realpath(__file__))
    
    # Definir las rutas locales donde se guardarán los archivos
    local_model_path = os.path.join(current_dir, request.model_path)
    local_tokenizer_path = os.path.join(current_dir, request.tokenizer_path)

    # Descargar los archivos si no existen (se hace de forma asíncrona)
    await download_files(model_url, tokenizer_url, local_model_path, local_tokenizer_path)

    # Cargar el modelo y tokenizer descargados
    print("Cargando el modelo y tokenizer en memoria...")
    model = executorch.load_model(local_model_path)
    tokenizer = executorch.load_tokenizer(local_tokenizer_path)
    
    # Configurar el modelo con los parámetros recibidos
    model.set_temperature(request.temperature)
    model.set_max_length(request.seq_len)
    print("Modelo y tokenizer cargados en memoria.")

# Ruta para generar texto (ahora es asíncrona)
@app.post("/generate/")
async def generate_text(request: Request):
    # Cargar el modelo si no ha sido cargado
    if model is None or tokenizer is None:
        await load_model(request)  # Esperamos la carga del modelo de forma asíncrona
    
    # Generar el texto con el prompt recibido
    output = model.generate(request.prompt)
    
    # Devolver el texto generado
    return {"generated_text": output}

# Código para ejecutar uvicorn desde el archivo Python
if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=7860)