Hjgugugjhuhjggg commited on
Commit
eb88339
verified
1 Parent(s): 84a589e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +91 -90
app.py CHANGED
@@ -1,108 +1,114 @@
1
  import os
2
  import logging
 
 
 
 
3
  import json
4
- from fastapi import FastAPI, HTTPException, Query
5
- from transformers import pipeline, AutoTokenizer, AutoModelForSequenceClassification
6
- import requests
7
- import uvicorn
8
- import threading
9
- from dotenv import load_dotenv
10
 
11
- load_dotenv()
12
-
13
- logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
14
- logger = logging.getLogger(__name__)
15
 
 
 
16
  GCS_BUCKET_NAME = os.getenv("GCS_BUCKET_NAME")
17
  GOOGLE_APPLICATION_CREDENTIALS_JSON = os.getenv("GOOGLE_APPLICATION_CREDENTIALS_JSON")
18
  HF_API_TOKEN = os.getenv("HF_API_TOKEN")
19
 
 
 
 
 
20
  try:
21
- from google.cloud import storage
22
- from google.auth import exceptions
23
- credentials_info = json.loads(GOOGLE_APPLICATION_CREDENTIALS_JSON)
24
- storage_client = storage.Client.from_service_account_info(credentials_info)
25
- bucket = storage_client.bucket(GCS_BUCKET_NAME)
 
26
  logger.info(f"Conexi贸n con Google Cloud Storage exitosa. Bucket: {GCS_BUCKET_NAME}")
27
- except ModuleNotFoundError as e:
28
- logger.error(f"Falta el m贸dulo requerido: {str(e)}")
29
- raise RuntimeError("El entorno no tiene instalado el paquete necesario 'google-cloud'.")
30
- except (exceptions.DefaultCredentialsError, json.JSONDecodeError, KeyError, ValueError) as e:
31
  logger.error(f"Error al cargar las credenciales o bucket: {e}")
32
  raise RuntimeError(f"Error al cargar las credenciales o bucket: {e}")
33
 
 
34
  app = FastAPI()
35
 
36
- HF_API_URL = "https://huggingface.co/api/models"
37
-
38
- def list_huggingface_models():
39
- headers = {"Authorization": f"Bearer {HF_API_TOKEN}"}
40
- response = requests.get(HF_API_URL, headers=headers)
41
- if response.status_code != 200:
42
- logger.error(f"Error al obtener la lista de modelos de Hugging Face: HTTP {response.status_code}")
43
- raise HTTPException(status_code=response.status_code, detail=f"Error al obtener la lista de modelos de Hugging Face")
44
- return [model["modelId"] for model in response.json()]
45
-
46
- def download_model_to_bucket(model_name: str):
47
- model_folder = f"{model_name}/"
48
- if bucket.blob(f"{model_folder}config.json").exists():
49
- logger.info(f"El modelo '{model_name}' ya est谩 en el bucket.")
50
- return
51
-
52
- hf_base_url = f"https://huggingface.co/{model_name}/resolve/main/"
53
- files = ["config.json", "pytorch_model.bin", "tokenizer.json"]
54
-
55
- for file_name in files:
56
- file_url = hf_base_url + file_name
57
- blob = bucket.blob(f"{model_folder}{file_name}")
58
- logger.info(f"Descargando {file_url} al bucket...")
59
-
60
- response = requests.get(file_url, stream=True)
61
- if response.status_code == 200:
62
- blob.upload_from_string(response.content)
63
- logger.info(f"Archivo {file_name} subido al bucket.")
64
- else:
65
- logger.error(f"No se pudo descargar el archivo {file_name}. HTTP {response.status_code}")
66
-
67
- def load_model_from_bucket(model_name: str):
68
- model_folder = f"{model_name}/"
69
- model_blob = bucket.blob(f"{model_folder}pytorch_model.bin")
70
- config_blob = bucket.blob(f"{model_folder}config.json")
71
- tokenizer_blob = bucket.blob(f"{model_folder}tokenizer.json")
72
-
73
- if not (model_blob.exists() and config_blob.exists() and tokenizer_blob.exists()):
74
- logger.error(f"Modelo no encontrado en el bucket: {model_name}")
75
- raise HTTPException(status_code=404, detail="Modelo no encontrado en el bucket. Aseg煤rese de haberlo descargado correctamente.")
76
-
77
- tokenizer = AutoTokenizer.from_pretrained(tokenizer_blob.download_as_bytes())
78
- model = AutoModelForSequenceClassification.from_pretrained(model_blob.download_as_bytes(), config=config_blob.download_as_bytes())
79
- return tokenizer, model
80
-
81
- def background_download_all_models():
82
- logger.info("Iniciando descarga de modelos en segundo plano...")
83
  try:
84
- model_names = list_huggingface_models()
85
- for model_name in model_names:
86
- try:
87
- download_model_to_bucket(model_name)
88
- except Exception as e:
89
- logger.error(f"Error al descargar el modelo {model_name}: {str(e)}")
90
- except HTTPException as e:
91
- logger.error(f"Error al obtener la lista de modelos de Hugging Face: {str(e)}")
 
 
 
 
 
 
 
92
 
93
- threading.Thread(target=background_download_all_models, daemon=True).start()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
 
95
  @app.post("/predict")
96
- def predict(
97
- model_name: str = Query(..., description="Nombre del modelo"),
98
- pipeline_task: str = Query(..., description="Tarea del pipeline (e.g., text-generation)"),
99
- input_text: str = Query(..., description="Texto de entrada para el modelo")
100
- ):
101
  try:
102
- download_model_to_bucket(model_name)
103
- tokenizer, model = load_model_from_bucket(model_name)
104
- nlp_pipeline = pipeline(task=pipeline_task, model=model, tokenizer=tokenizer)
 
 
 
 
 
 
105
  result = nlp_pipeline(input_text)
 
106
  return {"response": result}
107
 
108
  except HTTPException as e:
@@ -113,10 +119,5 @@ def predict(
113
  raise HTTPException(status_code=500, detail=str(e))
114
 
115
  if __name__ == "__main__":
116
- try:
117
- import ssl
118
- ssl_context = ssl.create_default_context()
119
- uvicorn.run(app, host="0.0.0.0", port=7860)
120
- except ModuleNotFoundError as e:
121
- logger.error(f"Falta el m贸dulo requerido: {str(e)}")
122
- raise RuntimeError("El entorno no tiene instalado el paquete necesario para manejar conexiones seguras.")
 
1
  import os
2
  import logging
3
+ from fastapi import FastAPI, HTTPException
4
+ from pydantic import BaseModel
5
+ from google.cloud import storage
6
+ from transformers import pipeline
7
  import json
8
+ from google.auth.exceptions import DefaultCredentialsError
 
 
 
 
 
9
 
10
+ # Configuraci贸n de GCS
 
 
 
11
 
12
+ # Cargar las variables de entorno
13
+ API_KEY = os.getenv("API_KEY")
14
  GCS_BUCKET_NAME = os.getenv("GCS_BUCKET_NAME")
15
  GOOGLE_APPLICATION_CREDENTIALS_JSON = os.getenv("GOOGLE_APPLICATION_CREDENTIALS_JSON")
16
  HF_API_TOKEN = os.getenv("HF_API_TOKEN")
17
 
18
+ # Configuraci贸n de logs
19
+ logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
20
+ logger = logging.getLogger(__name__)
21
+
22
  try:
23
+ # Intentar cargar las credenciales de servicio de GCS desde la variable de entorno
24
+ credentials_info = json.loads(GOOGLE_APPLICATION_CREDENTIALS_JSON) # Cargar el JSON de credenciales
25
+ storage_client = storage.Client.from_service_account_info(credentials_info) # Crear cliente de GCS
26
+ bucket = storage_client.bucket(GCS_BUCKET_NAME) # Acceder al bucket
27
+
28
+ # Verificaci贸n exitosa
29
  logger.info(f"Conexi贸n con Google Cloud Storage exitosa. Bucket: {GCS_BUCKET_NAME}")
30
+
31
+ except (DefaultCredentialsError, json.JSONDecodeError, KeyError, ValueError) as e:
32
+ # Manejo de errores en caso de que las credenciales sean incorrectas o faltantes
 
33
  logger.error(f"Error al cargar las credenciales o bucket: {e}")
34
  raise RuntimeError(f"Error al cargar las credenciales o bucket: {e}")
35
 
36
+ # Configurar la aplicaci贸n FastAPI
37
  app = FastAPI()
38
 
39
+ # Configuraci贸n de logs
40
+ logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
41
+ logger = logging.getLogger(__name__)
42
+
43
+ class PredictionRequest(BaseModel):
44
+ model_name: str
45
+ pipeline_task: str
46
+ input_text: str
47
+
48
+ # Funci贸n para obtener la URL del modelo desde GCS
49
+ def get_gcs_model_url(bucket_name: str, model_name: str):
50
+ """
51
+ Obtiene la URL del modelo desde GCS.
52
+ """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  try:
54
+ model_dir = f"models/{model_name}/"
55
+
56
+ # Verificar si la carpeta del modelo existe en GCS
57
+ bucket = storage_client.get_bucket(bucket_name)
58
+ blobs = bucket.list_blobs(prefix=model_dir)
59
+
60
+ # Verificar si existen archivos en el directorio del modelo
61
+ file_list = [blob.name for blob in blobs]
62
+ if not file_list:
63
+ raise HTTPException(status_code=404, detail="No se encontraron los archivos del modelo en GCS.")
64
+
65
+ # Construir la URL GCS del modelo (en este caso solo la ruta del directorio)
66
+ gcs_url = f"gs://{bucket_name}/{model_dir}"
67
+
68
+ return gcs_url
69
 
70
+ except Exception as e:
71
+ logger.error(f"Error al obtener la URL del modelo desde GCS: {str(e)}")
72
+ raise HTTPException(status_code=500, detail="Error al obtener la URL del modelo desde GCS.")
73
+
74
+ # Funci贸n para cargar el pipeline directamente desde GCS como URL
75
+ def load_pipeline_from_gcs(model_name: str, pipeline_task: str):
76
+ """
77
+ Carga el pipeline directamente desde la URL del modelo en GCS sin usar RAM ni almacenamiento temporal.
78
+ """
79
+ try:
80
+ # Obtener la URL del modelo desde GCS
81
+ model_url = get_gcs_model_url(GCS_BUCKET_NAME, model_name)
82
+
83
+ # Cargar el pipeline directamente desde la URL del modelo
84
+ nlp_pipeline = pipeline(
85
+ task=pipeline_task,
86
+ model=model_url, # Usamos la URL de GCS como modelo
87
+ )
88
+
89
+ return nlp_pipeline
90
+ except Exception as e:
91
+ logger.error(f"Error al cargar el pipeline desde GCS: {str(e)}")
92
+ raise HTTPException(status_code=500, detail="Error al cargar el pipeline desde GCS.")
93
 
94
+ # Endpoint para realizar la predicci贸n
95
  @app.post("/predict")
96
+ def predict(request: PredictionRequest):
97
+ """
98
+ Endpoint para recibir solicitudes POST con datos JSON y realizar la predicci贸n.
99
+ """
 
100
  try:
101
+ # Extraer los par谩metros de la solicitud JSON
102
+ model_name = request.model_name
103
+ pipeline_task = request.pipeline_task
104
+ input_text = request.input_text
105
+
106
+ # Cargar el pipeline directamente desde GCS sin usar RAM ni almacenamiento temporal
107
+ nlp_pipeline = load_pipeline_from_gcs(model_name, pipeline_task)
108
+
109
+ # Realizar la predicci贸n
110
  result = nlp_pipeline(input_text)
111
+
112
  return {"response": result}
113
 
114
  except HTTPException as e:
 
119
  raise HTTPException(status_code=500, detail=str(e))
120
 
121
  if __name__ == "__main__":
122
+ import uvicorn
123
+ uvicorn.run(app, host="0.0.0.0", port=7860)