Spaces:
Sleeping
Sleeping
Hjgugugjhuhjggg
commited on
Update app.py
Browse files
app.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
from huggingface_hub import HfApi
|
2 |
from fastapi import FastAPI, HTTPException
|
3 |
from pydantic import BaseModel, field_validator
|
4 |
import requests
|
@@ -77,109 +77,109 @@ class S3DirectStream:
|
|
77 |
def load_model_from_stream(self, model_prefix):
|
78 |
try:
|
79 |
logger.info(f"Loading model {model_prefix}...")
|
80 |
-
|
81 |
-
|
82 |
-
logger.
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
model = self._load_model(model_prefix, config, revision)
|
91 |
-
if model is None:
|
92 |
-
logger.error(f"Failed to load model {model_prefix}")
|
93 |
-
raise ValueError(f"Failed to load model {model_prefix}")
|
94 |
-
|
95 |
-
return model
|
96 |
-
|
97 |
except HTTPException as e:
|
98 |
logger.error(f"Error loading model: {e}")
|
99 |
-
raise
|
100 |
-
except Exception as e:
|
101 |
-
logger.exception(f"Unexpected error loading model: {e}")
|
102 |
-
raise HTTPException(status_code=500, detail=f"An unexpected error occurred while loading the model.")
|
103 |
-
|
104 |
-
def _load_config(self, model_prefix, revision):
|
105 |
-
try:
|
106 |
-
logger.info(f"Downloading config for {model_prefix} (revision {revision})...")
|
107 |
-
config_path = hf_hub_download(repo_id=model_prefix, filename="config.json", revision=revision)
|
108 |
-
with open(config_path, "r", encoding="utf-8") as f:
|
109 |
-
config_dict = json.load(f)
|
110 |
-
return AutoConfig.from_pretrained(model_prefix, **config_dict)
|
111 |
-
except Exception as e:
|
112 |
-
logger.error(f"Error loading config: {e}")
|
113 |
return None
|
114 |
|
115 |
-
def
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
for
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
|
141 |
-
|
142 |
-
|
143 |
-
|
|
|
|
|
|
|
|
|
|
|
144 |
|
145 |
def load_tokenizer_from_stream(self, model_prefix):
|
146 |
try:
|
147 |
logger.info(f"Loading tokenizer for {model_prefix}...")
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
raise ValueError(f"Failed to load tokenizer for {model_prefix}")
|
157 |
-
return tokenizer
|
158 |
except HTTPException as e:
|
159 |
logger.error(f"Error loading tokenizer: {e}")
|
160 |
return None
|
161 |
-
except Exception as e:
|
162 |
-
logger.exception(f"Unexpected error loading tokenizer: {e}")
|
163 |
-
raise HTTPException(status_code=500, detail=f"An unexpected error occurred while loading the tokenizer.")
|
164 |
|
165 |
-
def
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
173 |
|
174 |
|
175 |
def _get_model_files(self, model_prefix, revision="main"):
|
|
|
176 |
try:
|
177 |
-
|
178 |
-
|
179 |
-
|
|
|
|
|
|
|
180 |
return model_files
|
181 |
-
except
|
182 |
-
logger.error(f"Error retrieving model
|
|
|
|
|
|
|
183 |
raise HTTPException(status_code=500, detail=f"Error retrieving model files from Hugging Face") from e
|
184 |
|
185 |
def download_and_upload_to_s3_url(self, url, s3_key):
|
|
|
1 |
+
from huggingface_hub import HfApi
|
2 |
from fastapi import FastAPI, HTTPException
|
3 |
from pydantic import BaseModel, field_validator
|
4 |
import requests
|
|
|
77 |
def load_model_from_stream(self, model_prefix):
|
78 |
try:
|
79 |
logger.info(f"Loading model {model_prefix}...")
|
80 |
+
if self.file_exists_in_s3(f"{model_prefix}/config.json") and \
|
81 |
+
any(self.file_exists_in_s3(f"{model_prefix}/{file}") for file in self._get_model_files(model_prefix)):
|
82 |
+
logger.info(f"Model {model_prefix} found in S3. Loading...")
|
83 |
+
return self.load_model_from_existing_s3(model_prefix)
|
84 |
+
|
85 |
+
logger.info(f"Model {model_prefix} not found in S3. Downloading and uploading...")
|
86 |
+
self.download_and_upload_to_s3(model_prefix)
|
87 |
+
logger.info(f"Downloaded and uploaded {model_prefix}. Loading from S3...")
|
88 |
+
return self.load_model_from_stream(model_prefix)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
except HTTPException as e:
|
90 |
logger.error(f"Error loading model: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
return None
|
92 |
|
93 |
+
def load_model_from_existing_s3(self, model_prefix):
|
94 |
+
logger.info(f"Loading config for {model_prefix} from S3...")
|
95 |
+
config_stream = self.stream_from_s3(f"{model_prefix}/config.json")
|
96 |
+
config_dict = json.load(config_stream)
|
97 |
+
config = AutoConfig.from_pretrained(model_prefix, **config_dict)
|
98 |
+
logger.info(f"Config loaded for {model_prefix}.")
|
99 |
+
|
100 |
+
model_files = self._get_model_files(model_prefix)
|
101 |
+
if not model_files:
|
102 |
+
logger.error(f"No model files found for {model_prefix} in S3")
|
103 |
+
raise EnvironmentError(f"No model files found for {model_prefix} in S3")
|
104 |
+
|
105 |
+
state_dict = {}
|
106 |
+
for model_file in model_files:
|
107 |
+
model_path = os.path.join(model_prefix, model_file)
|
108 |
+
logger.info(f"Loading model file: {model_path}")
|
109 |
+
model_stream = self.stream_from_s3(model_path)
|
110 |
+
try:
|
111 |
+
if model_path.endswith(".safetensors"):
|
112 |
+
shard_state = safetensors.torch.load_stream(model_stream)
|
113 |
+
elif model_path.endswith(".bin"):
|
114 |
+
shard_state = torch.load(model_stream, map_location="cpu")
|
115 |
+
else:
|
116 |
+
logger.error(f"Unsupported model file type: {model_path}")
|
117 |
+
raise ValueError(f"Unsupported model file type: {model_path}")
|
118 |
|
119 |
+
state_dict.update(shard_state)
|
120 |
+
except Exception as e:
|
121 |
+
logger.exception(f"Error loading model file {model_path}: {e}")
|
122 |
+
raise
|
123 |
+
|
124 |
+
model = AutoModelForCausalLM.from_config(config)
|
125 |
+
model.load_state_dict(state_dict)
|
126 |
+
return model
|
127 |
|
128 |
def load_tokenizer_from_stream(self, model_prefix):
|
129 |
try:
|
130 |
logger.info(f"Loading tokenizer for {model_prefix}...")
|
131 |
+
if self.file_exists_in_s3(f"{model_prefix}/tokenizer.json"):
|
132 |
+
logger.info(f"Tokenizer for {model_prefix} found in S3. Loading...")
|
133 |
+
return self.load_tokenizer_from_existing_s3(model_prefix, config)
|
134 |
+
|
135 |
+
logger.info(f"Tokenizer for {model_prefix} not found in S3. Downloading and uploading...")
|
136 |
+
self.download_and_upload_to_s3(model_prefix)
|
137 |
+
logger.info(f"Downloaded and uploaded tokenizer for {model_prefix}. Loading from S3...")
|
138 |
+
return self.load_tokenizer_from_stream(model_prefix)
|
|
|
|
|
139 |
except HTTPException as e:
|
140 |
logger.error(f"Error loading tokenizer: {e}")
|
141 |
return None
|
|
|
|
|
|
|
142 |
|
143 |
+
def load_tokenizer_from_existing_s3(self, model_prefix, config):
|
144 |
+
logger.info(f"Loading tokenizer from S3 for {model_prefix}...")
|
145 |
+
tokenizer_stream = self.stream_from_s3(f"{model_prefix}/tokenizer.json")
|
146 |
+
tokenizer = AutoTokenizer.from_pretrained(None, config=config)
|
147 |
+
logger.info(f"Tokenizer loaded for {model_prefix}.")
|
148 |
+
return tokenizer
|
149 |
+
|
150 |
+
def download_and_upload_to_s3(self, model_prefix, revision="main"):
|
151 |
+
logger.info(f"Downloading and uploading model files for {model_prefix} to S3...")
|
152 |
+
config_url = f"https://huggingface.co/{model_prefix}/resolve/{revision}/config.json"
|
153 |
+
self.download_and_upload_to_s3_url(config_url, f"{model_prefix}/config.json")
|
154 |
+
|
155 |
+
model_files = self._get_model_files(model_prefix, revision)
|
156 |
+
for model_file in model_files:
|
157 |
+
url = f"https://huggingface.co/{model_prefix}/resolve/{revision}/{model_file}"
|
158 |
+
s3_key = f"{model_prefix}/{model_file}"
|
159 |
+
self.download_and_upload_to_s3_url(url, s3_key)
|
160 |
+
logger.info(f"Downloaded and uploaded {s3_key}")
|
161 |
+
|
162 |
+
tokenizer_url = f"https://huggingface.co/{model_prefix}/resolve/{revision}/tokenizer.json"
|
163 |
+
self.download_and_upload_to_s3_url(tokenizer_url, f"{model_prefix}/tokenizer.json")
|
164 |
+
|
165 |
+
logger.info(f"Finished downloading and uploading model files for {model_prefix}.")
|
166 |
|
167 |
|
168 |
def _get_model_files(self, model_prefix, revision="main"):
|
169 |
+
index_url = f"https://huggingface.co/{model_prefix}/resolve/{revision}/"
|
170 |
try:
|
171 |
+
index_response = requests.get(index_url)
|
172 |
+
index_response.raise_for_status()
|
173 |
+
logger.info(f"Hugging Face API Response: Status Code = {index_response.status_code}, Headers = {index_response.headers}")
|
174 |
+
index_content = index_response.text
|
175 |
+
logger.info(f"Index content: {index_content}")
|
176 |
+
model_files = [f for f in index_content.split('\n') if f.endswith(('.bin', '.safetensors'))]
|
177 |
return model_files
|
178 |
+
except requests.exceptions.RequestException as e:
|
179 |
+
logger.error(f"Error retrieving model index: {e}")
|
180 |
+
raise HTTPException(status_code=500, detail=f"Error retrieving model files from Hugging Face") from e
|
181 |
+
except (IndexError, ValueError) as e:
|
182 |
+
logger.error(f"Error parsing model file names from Hugging Face: {e}")
|
183 |
raise HTTPException(status_code=500, detail=f"Error retrieving model files from Hugging Face") from e
|
184 |
|
185 |
def download_and_upload_to_s3_url(self, url, s3_key):
|