BaoKhuong commited on
Commit
eed8f21
·
verified ·
1 Parent(s): bf4908c

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +26 -176
app.py CHANGED
@@ -477,6 +477,20 @@ def load_pipeline():
477
  print(f"Error details: {str(e)}")
478
  raise RuntimeError(f"Failed to load model: {str(e)}")
479
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
480
  def is_market_open() -> bool:
481
  """Check if the US stock market is currently open (legacy function for backward compatibility)"""
482
  return market_status_manager.get_status('US_STOCKS').is_open
@@ -990,190 +1004,26 @@ def make_prediction_enhanced(symbol: str, timeframe: str = "1d", prediction_days
990
 
991
  # Use predict_quantiles with proper formatting
992
  with torch.amp.autocast('cpu'):
993
- # Ensure all inputs are on CPU
994
- context = context.to(device)
995
-
996
- # Ensure context is properly shaped and on CPU
997
  if len(context.shape) == 1:
998
  context = context.unsqueeze(0)
999
  context = context.to(device)
1000
-
1001
- # Force all model components to CPU
1002
- pipe.model = pipe.model.to(device)
1003
-
1004
- # Move model to evaluation mode
1005
- pipe.model.eval()
1006
-
1007
- # Move all model parameters and buffers to CPU
1008
- for param in pipe.model.parameters():
1009
- param.data = param.data.to(device)
1010
- for buffer in pipe.model.buffers():
1011
- buffer.data = buffer.data.to(device)
1012
-
1013
- # Move all model submodules to CPU
1014
- for module in pipe.model.modules():
1015
- if hasattr(module, 'to'):
1016
- module.to(device)
1017
-
1018
- # Move all model attributes to CPU
1019
- for name, value in pipe.model.__dict__.items():
1020
- if isinstance(value, torch.Tensor):
1021
- pipe.model.__dict__[name] = value.to(device)
1022
-
1023
- # Move all model config tensors to CPU
1024
- if hasattr(pipe.model, 'config'):
1025
- for key, value in pipe.model.config.__dict__.items():
1026
- if isinstance(value, torch.Tensor):
1027
- setattr(pipe.model.config, key, value.to(device))
1028
-
1029
- # Move all pipeline tensors to CPU
1030
- for name, value in pipe.__dict__.items():
1031
- if isinstance(value, torch.Tensor):
1032
- setattr(pipe, name, value.to(device))
1033
-
1034
- # Ensure all model states are on CPU
1035
- if hasattr(pipe.model, 'state_dict'):
1036
- state_dict = pipe.model.state_dict()
1037
- for key in state_dict:
1038
- if isinstance(state_dict[key], torch.Tensor):
1039
- state_dict[key] = state_dict[key].to(device)
1040
- pipe.model.load_state_dict(state_dict)
1041
-
1042
- # Move any additional components to CPU
1043
- if hasattr(pipe, 'tokenizer'):
1044
- # Move tokenizer to CPU if it supports it
1045
- if hasattr(pipe.tokenizer, 'to'):
1046
- pipe.tokenizer = pipe.tokenizer.to(device)
1047
-
1048
- # Move all tokenizer tensors to CPU
1049
- for name, value in pipe.tokenizer.__dict__.items():
1050
- if isinstance(value, torch.Tensor):
1051
- setattr(pipe.tokenizer, name, value.to(device))
1052
-
1053
- # Handle MeanScaleUniformBins specific attributes
1054
- if hasattr(pipe.tokenizer, 'bins'):
1055
- if isinstance(pipe.tokenizer.bins, torch.Tensor):
1056
- pipe.tokenizer.bins = pipe.tokenizer.bins.to(device)
1057
-
1058
- if hasattr(pipe.tokenizer, 'scale'):
1059
- if isinstance(pipe.tokenizer.scale, torch.Tensor):
1060
- pipe.tokenizer.scale = pipe.tokenizer.scale.to(device)
1061
-
1062
- if hasattr(pipe.tokenizer, 'mean'):
1063
- if isinstance(pipe.tokenizer.mean, torch.Tensor):
1064
- pipe.tokenizer.mean = pipe.tokenizer.mean.to(device)
1065
-
1066
- # Move any additional tensors in the tokenizer's attributes to CPU
1067
- for name, value in pipe.tokenizer.__dict__.items():
1068
- if isinstance(value, torch.Tensor):
1069
- pipe.tokenizer.__dict__[name] = value.to(device)
1070
-
1071
- # Remove the EOS token handling since MeanScaleUniformBins doesn't use it
1072
- if hasattr(pipe.tokenizer, '_append_eos_token'):
1073
- # Create a wrapper that just returns the input tensors
1074
- def wrapped_append_eos(token_ids, attention_mask):
1075
- return token_ids, attention_mask
1076
- pipe.tokenizer._append_eos_token = wrapped_append_eos
1077
-
1078
- # Force synchronization for CPU (no-op for CPU)
1079
- # torch.cuda.synchronize() # Not needed for CPU
1080
-
1081
- # Ensure all model components are in eval mode
1082
- pipe.model.eval()
1083
-
1084
  # Fix generation configuration to prevent min_length errors
1085
  if hasattr(pipe.model, 'config'):
1086
- # Ensure generation config is properly set
1087
- if hasattr(pipe.model.config, 'generation_config'):
1088
- # Reset generation config to safe defaults
1089
- pipe.model.config.generation_config.min_length = 0
1090
- pipe.model.config.generation_config.max_length = 512
1091
- pipe.model.config.generation_config.do_sample = False
1092
- pipe.model.config.generation_config.num_beams = 1
1093
- else:
1094
- # Create a safe generation config if it doesn't exist
1095
  pipe.model.config.generation_config = GenerationConfig(
1096
- min_length=0,
1097
- max_length=512,
1098
- do_sample=False,
1099
- num_beams=1
1100
  )
1101
-
1102
- # Move any additional tensors in the model's config to CPU
1103
- if hasattr(pipe.model, 'config'):
1104
- for key, value in pipe.model.config.__dict__.items():
1105
- if isinstance(value, torch.Tensor):
1106
- setattr(pipe.model.config, key, value.to(device))
1107
-
1108
- # Move any additional tensors in the model's state dict to CPU
1109
- if hasattr(pipe.model, 'state_dict'):
1110
- state_dict = pipe.model.state_dict()
1111
- for key in state_dict:
1112
- if isinstance(state_dict[key], torch.Tensor):
1113
- state_dict[key] = state_dict[key].to(device)
1114
- pipe.model.load_state_dict(state_dict)
1115
-
1116
- # Move any additional tensors in the model's buffers to CPU
1117
- for name, buffer in pipe.model.named_buffers():
1118
- if buffer is not None:
1119
- pipe.model.register_buffer(name, buffer.to(device))
1120
-
1121
- # Move any additional tensors in the model's parameters to CPU
1122
- for name, param in pipe.model.named_parameters():
1123
- if param is not None:
1124
- param.data = param.data.to(device)
1125
-
1126
- # Move any additional tensors in the model's attributes to GPU
1127
- for name, value in pipe.model.__dict__.items():
1128
- if isinstance(value, torch.Tensor):
1129
- pipe.model.__dict__[name] = value.to(device)
1130
-
1131
- # Move any additional tensors in the model's modules to GPU
1132
- for name, module in pipe.model.named_modules():
1133
- if hasattr(module, 'to'):
1134
- module.to(device)
1135
- # Move any tensors in the module's __dict__
1136
- for key, value in module.__dict__.items():
1137
- if isinstance(value, torch.Tensor):
1138
- setattr(module, key, value.to(device))
1139
-
1140
- # Force synchronization for CPU (no-op for CPU)
1141
- # torch.cuda.synchronize() # Not needed for CPU
1142
-
1143
- # Ensure tokenizer is on GPU and all its tensors are on GPU
1144
- if hasattr(pipe, 'tokenizer'):
1145
- # Move tokenizer to CPU if it supports it
1146
- if hasattr(pipe.tokenizer, 'to'):
1147
- pipe.tokenizer = pipe.tokenizer.to(device)
1148
-
1149
- # Move all tokenizer tensors to CPU
1150
- for name, value in pipe.tokenizer.__dict__.items():
1151
- if isinstance(value, torch.Tensor):
1152
- setattr(pipe.tokenizer, name, value.to(device))
1153
-
1154
- # Handle MeanScaleUniformBins specific attributes
1155
- if hasattr(pipe.tokenizer, 'bins'):
1156
- if isinstance(pipe.tokenizer.bins, torch.Tensor):
1157
- pipe.tokenizer.bins = pipe.tokenizer.bins.to(device)
1158
-
1159
- if hasattr(pipe.tokenizer, 'scale'):
1160
- if isinstance(pipe.tokenizer.scale, torch.Tensor):
1161
- pipe.tokenizer.scale = pipe.tokenizer.scale.to(device)
1162
-
1163
- if hasattr(pipe.tokenizer, 'mean'):
1164
- if isinstance(pipe.tokenizer.mean, torch.Tensor):
1165
- pipe.tokenizer.mean = pipe.tokenizer.mean.to(device)
1166
-
1167
- # Move any additional tensors in the tokenizer's attributes to CPU
1168
- for name, value in pipe.tokenizer.__dict__.items():
1169
- if isinstance(value, torch.Tensor):
1170
- pipe.tokenizer.__dict__[name] = value.to(device)
1171
-
1172
- # Force synchronization for CPU (no-op for CPU)
1173
- # torch.cuda.synchronize() # Not needed for CPU
1174
-
1175
  # Make prediction with proper parameters
1176
- # Use the standard quantile levels as per Chronos documentation
1177
  try:
1178
  quantiles, mean = pipe.predict_quantiles(
1179
  context=context,
 
477
  print(f"Error details: {str(e)}")
478
  raise RuntimeError(f"Failed to load model: {str(e)}")
479
 
480
+ def _ensure_pipeline_cpu(pipe):
481
+ """Ensure Chronos pipeline model/tokenizer are on CPU and in eval mode."""
482
+ try:
483
+ pipe.model = pipe.model.to(torch.device("cpu"))
484
+ pipe.model.eval()
485
+ except Exception:
486
+ pass
487
+ try:
488
+ tok = getattr(pipe, 'tokenizer', None)
489
+ if tok is not None and hasattr(tok, 'to'):
490
+ pipe.tokenizer = tok.to(torch.device("cpu"))
491
+ except Exception:
492
+ pass
493
+
494
  def is_market_open() -> bool:
495
  """Check if the US stock market is currently open (legacy function for backward compatibility)"""
496
  return market_status_manager.get_status('US_STOCKS').is_open
 
1004
 
1005
  # Use predict_quantiles with proper formatting
1006
  with torch.amp.autocast('cpu'):
1007
+ # Ensure inputs and pipeline are on CPU
 
 
 
1008
  if len(context.shape) == 1:
1009
  context = context.unsqueeze(0)
1010
  context = context.to(device)
1011
+ _ensure_pipeline_cpu(pipe)
1012
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1013
  # Fix generation configuration to prevent min_length errors
1014
  if hasattr(pipe.model, 'config'):
1015
+ gen_cfg = getattr(pipe.model.config, 'generation_config', None)
1016
+ if gen_cfg is None:
 
 
 
 
 
 
 
1017
  pipe.model.config.generation_config = GenerationConfig(
1018
+ min_length=0, max_length=512, do_sample=False, num_beams=1
 
 
 
1019
  )
1020
+ else:
1021
+ gen_cfg.min_length = 0
1022
+ gen_cfg.max_length = 512
1023
+ gen_cfg.do_sample = False
1024
+ gen_cfg.num_beams = 1
1025
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1026
  # Make prediction with proper parameters
 
1027
  try:
1028
  quantiles, mean = pipe.predict_quantiles(
1029
  context=context,