Hjgugugjhuhjggg commited on
Commit
c1d4983
verified
1 Parent(s): 9214e9b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +79 -61
app.py CHANGED
@@ -1,14 +1,12 @@
1
  import os
2
- import logging
3
- import boto3
4
  from fastapi import FastAPI, HTTPException
5
  from pydantic import BaseModel
6
  from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
7
  from huggingface_hub import hf_hub_download
8
- import torch
9
- import safetensors
10
  import asyncio
11
- from tqdm import tqdm # Importar tqdm para la barra de progreso
12
 
13
  logger = logging.getLogger(__name__)
14
  logger.setLevel(logging.INFO)
@@ -55,14 +53,11 @@ class S3DirectStream:
55
 
56
  def _stream_from_s3(self, key):
57
  try:
58
- logger.info(f"Descargando archivo {key} desde S3...")
59
  response = self.s3_client.get_object(Bucket=self.bucket_name, Key=key)
60
- file_content = response['Body'].read() # This returns a bytes object
61
- return file_content
62
  except self.s3_client.exceptions.NoSuchKey:
63
  raise HTTPException(status_code=404, detail=f"El archivo {key} no existe en el bucket S3.")
64
  except Exception as e:
65
- logger.error(f"Error al descargar {key} desde S3: {str(e)}")
66
  raise HTTPException(status_code=500, detail=f"Error al descargar {key} desde S3: {str(e)}")
67
 
68
  async def get_model_file_parts(self, model_name):
@@ -72,48 +67,71 @@ class S3DirectStream:
72
  def _get_model_file_parts(self, model_name):
73
  try:
74
  model_name = model_name.replace("/", "-").lower()
75
- logger.info(f"Obteniendo archivos del modelo {model_name} desde S3...")
76
  files = self.s3_client.list_objects_v2(Bucket=self.bucket_name, Prefix=model_name)
77
  model_files = [obj['Key'] for obj in files.get('Contents', []) if model_name in obj['Key']]
78
- if not model_files:
79
- raise HTTPException(status_code=404, detail=f"Archivos del modelo {model_name} no encontrados.")
80
  return model_files
81
  except Exception as e:
82
  raise HTTPException(status_code=500, detail=f"Error al obtener archivos del modelo {model_name} desde S3: {e}")
83
 
84
  async def load_model_from_s3(self, model_name):
85
  try:
86
- logger.info(f"Cargando modelo {model_name} desde S3...")
87
  model_name = model_name.replace("/", "-").lower()
88
  model_files = await self.get_model_file_parts(model_name)
89
 
90
- if 'pytorch_model.bin' not in model_files:
91
- raise HTTPException(status_code=404, detail="Archivo 'pytorch_model.bin' no encontrado en S3")
92
- if 'tokenizer.json' not in model_files:
93
- raise HTTPException(status_code=404, detail="Archivo 'tokenizer.json' no encontrado en S3")
94
 
95
- model_bytes = await self.stream_from_s3(f"{model_name}/pytorch_model.bin")
96
- logger.info(f"Modelo descargado correctamente. Cargando el modelo en memoria...")
97
- model = AutoModelForCausalLM.from_pretrained(model_bytes, config=model_name)
 
 
 
 
 
 
 
 
98
  return model
99
 
100
  except HTTPException as e:
101
  raise e
102
  except Exception as e:
103
- logger.error(f"Error al cargar el modelo desde S3: {e}")
104
  raise HTTPException(status_code=500, detail=f"Error al cargar el modelo desde S3: {e}")
105
 
106
  async def load_tokenizer_from_s3(self, model_name):
107
  try:
108
- logger.info(f"Cargando tokenizer del modelo {model_name} desde S3...")
109
  model_name = model_name.replace("/", "-").lower()
110
- tokenizer_bytes = await self.stream_from_s3(f"{model_name}/tokenizer.json")
111
- tokenizer = AutoTokenizer.from_pretrained(tokenizer_bytes)
 
 
 
 
 
112
  return tokenizer
113
  except Exception as e:
114
- logger.error(f"Error al cargar el tokenizer desde S3: {e}")
115
  raise HTTPException(status_code=500, detail=f"Error al cargar el tokenizer desde S3: {e}")
116
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  async def download_and_upload_to_s3(self, model_name, force_download=False):
118
  try:
119
  if force_download:
@@ -121,84 +139,84 @@ class S3DirectStream:
121
 
122
  model_name = model_name.replace("/", "-").lower()
123
 
124
- if not await self.file_exists_in_s3(f"{model_name}/pytorch_model.bin") or not await self.file_exists_in_s3(f"{model_name}/tokenizer.json"):
125
- logger.info(f"Descargando archivos del modelo {model_name} desde Hugging Face...")
126
- model_file = hf_hub_download(repo_id=model_name, filename="pytorch_model.bin", token=HUGGINGFACE_HUB_TOKEN, force_download=force_download)
127
  tokenizer_file = hf_hub_download(repo_id=model_name, filename="tokenizer.json", token=HUGGINGFACE_HUB_TOKEN, force_download=force_download)
128
 
129
  await self.create_s3_folders(f"{model_name}/")
130
 
131
- if not await self.file_exists_in_s3(f"{model_name}/pytorch_model.bin"):
132
- with open(model_file, "rb") as file:
133
- logger.info(f"Cargando archivo {model_name}/pytorch_model.bin a S3...")
134
- self.s3_client.put_object(Bucket=self.bucket_name, Key=f"{model_name}/pytorch_model.bin", Body=file)
135
 
136
  if not await self.file_exists_in_s3(f"{model_name}/tokenizer.json"):
137
  with open(tokenizer_file, "rb") as file:
138
- logger.info(f"Cargando archivo {model_name}/tokenizer.json a S3...")
139
  self.s3_client.put_object(Bucket=self.bucket_name, Key=f"{model_name}/tokenizer.json", Body=file)
140
  else:
141
  logger.info(f"Los archivos del modelo {model_name} ya existen en S3. No es necesario descargarlos de nuevo.")
142
 
143
  except Exception as e:
144
- logger.error(f"Error al descargar o cargar archivos desde Hugging Face a S3: {e}")
145
  raise HTTPException(status_code=500, detail=f"Error al descargar o cargar archivos desde Hugging Face a S3: {e}")
146
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
 
148
  @app.post("/generate")
149
  async def generate(request: GenerateRequest):
150
  try:
151
- task_type = request.task_type
152
  model_name = request.model_name
153
  input_text = request.input_text
154
-
155
- logger.info(f"Iniciando la generaci贸n para el modelo {model_name} con el tipo de tarea {task_type}...")
156
-
157
  s3_direct_stream = S3DirectStream(S3_BUCKET_NAME)
158
-
 
159
  model = await s3_direct_stream.load_model_from_s3(model_name)
160
  tokenizer = await s3_direct_stream.load_tokenizer_from_s3(model_name)
161
-
162
- logger.info(f"Modelo y tokenizer cargados correctamente. Procesando tarea {task_type}...")
163
-
164
  if task_type == "text-to-text":
165
  generator = pipeline("text-generation", model=model, tokenizer=tokenizer, device=0)
166
  result = generator(input_text, max_length=MAX_TOKENS, num_return_sequences=1)
167
- logger.info(f"Generaci贸n completada: {result[0]['generated_text']}")
168
  return {"result": result[0]["generated_text"]}
169
 
170
  elif task_type == "text-to-image":
171
  generator = pipeline("text-to-image", model=model, tokenizer=tokenizer, device=0)
172
  image = generator(input_text)
173
- logger.info(f"Imagen generada.")
174
- return {"image": image}
175
-
176
- elif task_type == "text-to-video":
177
- generator = pipeline("text-to-video", model=model, tokenizer=tokenizer, device=0)
178
- video = generator(input_text)
179
- logger.info(f"Video generado.")
180
- return {"video": video}
181
 
182
  elif task_type == "text-to-speech":
183
  generator = pipeline("text-to-speech", model=model, tokenizer=tokenizer, device=0)
184
  audio = generator(input_text)
185
- logger.info(f"Audio generado.")
186
- return {"audio": audio}
187
 
188
- elif task_type == "text-to-audio":
189
- generator = pipeline("text-to-audio", model=model, tokenizer=tokenizer, device=0)
190
- audio = generator(input_text)
191
- logger.info(f"Audio generado.")
192
- return {"audio": audio}
193
 
194
  else:
195
- raise HTTPException(status_code=400, detail="Tipo de tarea no soportado.")
196
 
197
  except HTTPException as e:
198
  raise e
199
  except Exception as e:
200
- raise HTTPException(status_code=500, detail=f"Error en la generaci贸n: {str(e)}")
201
-
202
 
203
  if __name__ == "__main__":
204
  import uvicorn
 
1
  import os
2
+ import json
 
3
  from fastapi import FastAPI, HTTPException
4
  from pydantic import BaseModel
5
  from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
6
  from huggingface_hub import hf_hub_download
7
+ import boto3
8
+ import logging
9
  import asyncio
 
10
 
11
  logger = logging.getLogger(__name__)
12
  logger.setLevel(logging.INFO)
 
53
 
54
  def _stream_from_s3(self, key):
55
  try:
 
56
  response = self.s3_client.get_object(Bucket=self.bucket_name, Key=key)
57
+ return response['Body'].read() # This is a bytes object
 
58
  except self.s3_client.exceptions.NoSuchKey:
59
  raise HTTPException(status_code=404, detail=f"El archivo {key} no existe en el bucket S3.")
60
  except Exception as e:
 
61
  raise HTTPException(status_code=500, detail=f"Error al descargar {key} desde S3: {str(e)}")
62
 
63
  async def get_model_file_parts(self, model_name):
 
67
  def _get_model_file_parts(self, model_name):
68
  try:
69
  model_name = model_name.replace("/", "-").lower()
 
70
  files = self.s3_client.list_objects_v2(Bucket=self.bucket_name, Prefix=model_name)
71
  model_files = [obj['Key'] for obj in files.get('Contents', []) if model_name in obj['Key']]
 
 
72
  return model_files
73
  except Exception as e:
74
  raise HTTPException(status_code=500, detail=f"Error al obtener archivos del modelo {model_name} desde S3: {e}")
75
 
76
  async def load_model_from_s3(self, model_name):
77
  try:
 
78
  model_name = model_name.replace("/", "-").lower()
79
  model_files = await self.get_model_file_parts(model_name)
80
 
81
+ if not model_files:
82
+ await self.download_and_upload_to_s3(model_name)
 
 
83
 
84
+ config_data = await self.stream_from_s3(f"{model_name}/config.json")
85
+ if not config_data:
86
+ raise HTTPException(status_code=500, detail=f"El archivo de configuraci贸n {model_name}/config.json est谩 vac铆o o no se pudo leer.")
87
+
88
+ # Ensure config_data is a string or bytes-like object
89
+ if isinstance(config_data, bytes):
90
+ config_data = config_data.decode("utf-8") # Decodificar los bytes a string si es necesario
91
+
92
+ config_json = json.loads(config_data) # Ahora podemos usar json.loads sin problema
93
+
94
+ model = AutoModelForCausalLM.from_pretrained(f"s3://{self.bucket_name}/{model_name}", config=config_json, from_tf=False)
95
  return model
96
 
97
  except HTTPException as e:
98
  raise e
99
  except Exception as e:
 
100
  raise HTTPException(status_code=500, detail=f"Error al cargar el modelo desde S3: {e}")
101
 
102
  async def load_tokenizer_from_s3(self, model_name):
103
  try:
 
104
  model_name = model_name.replace("/", "-").lower()
105
+ tokenizer_data = await self.stream_from_s3(f"{model_name}/tokenizer.json")
106
+
107
+ # Ensure tokenizer_data is a string or bytes-like object
108
+ if isinstance(tokenizer_data, bytes):
109
+ tokenizer_data = tokenizer_data.decode("utf-8") # Decodificar los bytes a string si es necesario
110
+
111
+ tokenizer = AutoTokenizer.from_pretrained(f"s3://{self.bucket_name}/{model_name}")
112
  return tokenizer
113
  except Exception as e:
 
114
  raise HTTPException(status_code=500, detail=f"Error al cargar el tokenizer desde S3: {e}")
115
 
116
+ async def create_s3_folders(self, s3_key):
117
+ try:
118
+ folder_keys = s3_key.split('-')
119
+ for i in range(1, len(folder_keys)):
120
+ folder_key = '-'.join(folder_keys[:i]) + '/'
121
+ if not await self.file_exists_in_s3(folder_key):
122
+ logger.info(f"Creando carpeta en S3: {folder_key}")
123
+ self.s3_client.put_object(Bucket=self.bucket_name, Key=folder_key, Body='')
124
+
125
+ except Exception as e:
126
+ raise HTTPException(status_code=500, detail=f"Error al crear carpetas en S3: {e}")
127
+
128
+ async def file_exists_in_s3(self, s3_key):
129
+ try:
130
+ self.s3_client.head_object(Bucket=self.bucket_name, Key=s3_key)
131
+ return True
132
+ except self.s3_client.exceptions.ClientError:
133
+ return False
134
+
135
  async def download_and_upload_to_s3(self, model_name, force_download=False):
136
  try:
137
  if force_download:
 
139
 
140
  model_name = model_name.replace("/", "-").lower()
141
 
142
+ if not await self.file_exists_in_s3(f"{model_name}/config.json") or not await self.file_exists_in_s3(f"{model_name}/tokenizer.json"):
143
+ config_file = hf_hub_download(repo_id=model_name, filename="config.json", token=HUGGINGFACE_HUB_TOKEN, force_download=force_download)
 
144
  tokenizer_file = hf_hub_download(repo_id=model_name, filename="tokenizer.json", token=HUGGINGFACE_HUB_TOKEN, force_download=force_download)
145
 
146
  await self.create_s3_folders(f"{model_name}/")
147
 
148
+ if not await self.file_exists_in_s3(f"{model_name}/config.json"):
149
+ with open(config_file, "rb") as file:
150
+ self.s3_client.put_object(Bucket=self.bucket_name, Key=f"{model_name}/config.json", Body=file)
 
151
 
152
  if not await self.file_exists_in_s3(f"{model_name}/tokenizer.json"):
153
  with open(tokenizer_file, "rb") as file:
 
154
  self.s3_client.put_object(Bucket=self.bucket_name, Key=f"{model_name}/tokenizer.json", Body=file)
155
  else:
156
  logger.info(f"Los archivos del modelo {model_name} ya existen en S3. No es necesario descargarlos de nuevo.")
157
 
158
  except Exception as e:
 
159
  raise HTTPException(status_code=500, detail=f"Error al descargar o cargar archivos desde Hugging Face a S3: {e}")
160
 
161
+ async def resume_download(self, model_name):
162
+ try:
163
+ logger.info(f"Reanudando la descarga del modelo {model_name} desde Hugging Face.")
164
+ config_file = hf_hub_download(repo_id=model_name, filename="config.json", token=HUGGINGFACE_HUB_TOKEN, resume_download=True)
165
+ tokenizer_file = hf_hub_download(repo_id=model_name, filename="tokenizer.json", token=HUGGINGFACE_HUB_TOKEN, resume_download=True)
166
+
167
+ if not await self.file_exists_in_s3(f"{model_name}/config.json"):
168
+ with open(config_file, "rb") as file:
169
+ self.s3_client.put_object(Bucket=self.bucket_name, Key=f"{model_name}/config.json", Body=file)
170
+
171
+ if not await self.file_exists_in_s3(f"{model_name}/tokenizer.json"):
172
+ with open(tokenizer_file, "rb") as file:
173
+ self.s3_client.put_object(Bucket=self.bucket_name, Key=f"{model_name}/tokenizer.json", Body=file)
174
+
175
+ except Exception as e:
176
+ raise HTTPException(status_code=500, detail=f"Error al reanudar la descarga del modelo: {e}")
177
 
178
  @app.post("/generate")
179
  async def generate(request: GenerateRequest):
180
  try:
 
181
  model_name = request.model_name
182
  input_text = request.input_text
183
+ task_type = request.task_type
184
+
185
+ # Create an instance of S3DirectStream
186
  s3_direct_stream = S3DirectStream(S3_BUCKET_NAME)
187
+
188
+ # Load model and tokenizer
189
  model = await s3_direct_stream.load_model_from_s3(model_name)
190
  tokenizer = await s3_direct_stream.load_tokenizer_from_s3(model_name)
191
+
192
+ # Generate based on task type
 
193
  if task_type == "text-to-text":
194
  generator = pipeline("text-generation", model=model, tokenizer=tokenizer, device=0)
195
  result = generator(input_text, max_length=MAX_TOKENS, num_return_sequences=1)
 
196
  return {"result": result[0]["generated_text"]}
197
 
198
  elif task_type == "text-to-image":
199
  generator = pipeline("text-to-image", model=model, tokenizer=tokenizer, device=0)
200
  image = generator(input_text)
201
+ return {"result": image}
 
 
 
 
 
 
 
202
 
203
  elif task_type == "text-to-speech":
204
  generator = pipeline("text-to-speech", model=model, tokenizer=tokenizer, device=0)
205
  audio = generator(input_text)
206
+ return {"result": audio}
 
207
 
208
+ elif task_type == "text-to-video":
209
+ generator = pipeline("text-to-video", model=model, tokenizer=tokenizer, device=0)
210
+ video = generator(input_text)
211
+ return {"result": video}
 
212
 
213
  else:
214
+ raise HTTPException(status_code=400, detail="Tipo de tarea no soportada")
215
 
216
  except HTTPException as e:
217
  raise e
218
  except Exception as e:
219
+ raise HTTPException(status_code=500, detail=str(e))
 
220
 
221
  if __name__ == "__main__":
222
  import uvicorn