Hjgugugjhuhjggg commited on
Commit
b88653d
·
verified ·
1 Parent(s): 3d5534f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +86 -86
app.py CHANGED
@@ -1,4 +1,4 @@
1
- from huggingface_hub import HfApi, hf_hub_download
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
- revision = self._get_latest_revision(model_prefix)
81
- if revision is None:
82
- logger.error(f"Could not determine revision for {model_prefix}")
83
- raise ValueError(f"Could not determine revision for {model_prefix}")
84
-
85
- config = self._load_config(model_prefix, revision)
86
- if config is None:
87
- logger.error(f"Failed to load config for {model_prefix}")
88
- raise ValueError(f"Failed to load config for {model_prefix}")
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 _load_model(self, model_prefix, config, revision):
116
- try:
117
- logger.info(f"Downloading model files for {model_prefix} (revision {revision})...")
118
- model_files = self._get_model_files(model_prefix, revision)
119
- if not model_files:
120
- logger.error(f"No model files found for {model_prefix}")
121
- return None
122
-
123
- state_dict = {}
124
- for model_file in model_files:
125
- logger.info(f"Downloading model file: {model_file}")
126
- file_path = hf_hub_download(repo_id=model_prefix, filename=model_file, revision=revision)
127
- with open(file_path, "rb") as f:
128
- if model_file.endswith(".safetensors"):
129
- shard_state = safetensors.torch.load_file(file_path)
130
- elif model_file.endswith(".bin"):
131
- shard_state = torch.load(f, map_location="cpu")
132
- else:
133
- logger.error(f"Unsupported model file type: {model_file}")
134
- raise ValueError(f"Unsupported model file type: {model_file}")
135
- state_dict.update(shard_state)
136
-
137
- model = AutoModelForCausalLM.from_config(config)
138
- model.load_state_dict(state_dict)
139
- return model
140
 
141
- except Exception as e:
142
- logger.exception(f"Error loading model: {e}")
143
- return None
 
 
 
 
 
144
 
145
  def load_tokenizer_from_stream(self, model_prefix):
146
  try:
147
  logger.info(f"Loading tokenizer for {model_prefix}...")
148
- revision = self._get_latest_revision(model_prefix)
149
- if revision is None:
150
- logger.error(f"Could not determine revision for {model_prefix}")
151
- raise ValueError(f"Could not determine revision for {model_prefix}")
152
-
153
- tokenizer = self._load_tokenizer(model_prefix, revision)
154
- if tokenizer is None:
155
- logger.error(f"Failed to load tokenizer for {model_prefix}")
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 _load_tokenizer(self, model_prefix, revision):
166
- try:
167
- logger.info(f"Downloading tokenizer for {model_prefix} (revision {revision})...")
168
- tokenizer_path = hf_hub_download(repo_id=model_prefix, filename="tokenizer.json", revision=revision)
169
- return AutoTokenizer.from_pretrained(tokenizer_path)
170
- except Exception as e:
171
- logger.error(f"Error loading tokenizer: {e}")
172
- return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
 
174
 
175
  def _get_model_files(self, model_prefix, revision="main"):
 
176
  try:
177
- api = HfApi()
178
- model_files = api.list_repo_files(model_prefix, revision=revision)
179
- model_files = [file["rfilename"] for file in model_files if file["rfilename"].endswith(('.bin', '.safetensors'))]
 
 
 
180
  return model_files
181
- except Exception as e:
182
- logger.error(f"Error retrieving model files 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):
 
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):