Spaces:
Paused
Paused
Tonic commited on
fix generation config and issue in chronos
Browse files
app.py
CHANGED
|
@@ -21,6 +21,7 @@ from scipy.optimize import minimize
|
|
| 21 |
import warnings
|
| 22 |
import threading
|
| 23 |
from dataclasses import dataclass
|
|
|
|
| 24 |
warnings.filterwarnings('ignore')
|
| 25 |
|
| 26 |
# Additional imports for advanced features
|
|
@@ -1044,6 +1045,18 @@ def make_prediction_enhanced(symbol: str, timeframe: str = "1d", prediction_days
|
|
| 1044 |
# Convert to tensor and ensure proper shape and device
|
| 1045 |
context = torch.tensor(normalized_prices, dtype=dtype, device=device)
|
| 1046 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1047 |
# Adjust prediction length based on timeframe
|
| 1048 |
if timeframe == "1d":
|
| 1049 |
max_prediction_length = chronos_context_size # 64 days
|
|
@@ -1057,18 +1070,22 @@ def make_prediction_enhanced(symbol: str, timeframe: str = "1d", prediction_days
|
|
| 1057 |
max_prediction_length = chronos_context_size # 64 intervals
|
| 1058 |
actual_prediction_length = min(prediction_days * 96, max_prediction_length)
|
| 1059 |
trim_length = prediction_days * 96
|
| 1060 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1061 |
|
| 1062 |
# Use predict_quantiles with proper formatting
|
| 1063 |
with torch.amp.autocast('cuda'):
|
| 1064 |
# Ensure all inputs are on GPU
|
| 1065 |
context = context.to(device)
|
| 1066 |
|
| 1067 |
-
#
|
| 1068 |
-
|
| 1069 |
-
|
| 1070 |
-
|
| 1071 |
-
prediction_length = torch.tensor(actual_prediction_length, device=device, dtype=torch.long)
|
| 1072 |
|
| 1073 |
# Force all model components to GPU
|
| 1074 |
pipe.model = pipe.model.to(device)
|
|
@@ -1076,11 +1093,6 @@ def make_prediction_enhanced(symbol: str, timeframe: str = "1d", prediction_days
|
|
| 1076 |
# Move model to evaluation mode
|
| 1077 |
pipe.model.eval()
|
| 1078 |
|
| 1079 |
-
# Ensure context is properly shaped and on GPU
|
| 1080 |
-
if len(context.shape) == 1:
|
| 1081 |
-
context = context.unsqueeze(0)
|
| 1082 |
-
context = context.to(device)
|
| 1083 |
-
|
| 1084 |
# Move all model parameters and buffers to GPU
|
| 1085 |
for param in pipe.model.parameters():
|
| 1086 |
param.data = param.data.to(device)
|
|
@@ -1158,6 +1170,24 @@ def make_prediction_enhanced(symbol: str, timeframe: str = "1d", prediction_days
|
|
| 1158 |
# Ensure all model components are in eval mode
|
| 1159 |
pipe.model.eval()
|
| 1160 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1161 |
# Move any additional tensors in the model's config to GPU
|
| 1162 |
if hasattr(pipe.model, 'config'):
|
| 1163 |
for key, value in pipe.model.config.__dict__.items():
|
|
@@ -1231,12 +1261,34 @@ def make_prediction_enhanced(symbol: str, timeframe: str = "1d", prediction_days
|
|
| 1231 |
# Force synchronization again to ensure all tensors are on GPU
|
| 1232 |
torch.cuda.synchronize()
|
| 1233 |
|
| 1234 |
-
# Make prediction
|
| 1235 |
-
|
| 1236 |
-
|
| 1237 |
-
|
| 1238 |
-
|
| 1239 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1240 |
|
| 1241 |
if quantiles is None or mean is None or len(quantiles) == 0 or len(mean) == 0:
|
| 1242 |
raise ValueError("Chronos returned empty prediction")
|
|
@@ -1310,12 +1362,32 @@ def make_prediction_enhanced(symbol: str, timeframe: str = "1d", prediction_days
|
|
| 1310 |
context = context.unsqueeze(0)
|
| 1311 |
|
| 1312 |
next_length = min(max_prediction_length, remaining_steps)
|
|
|
|
|
|
|
|
|
|
| 1313 |
with torch.amp.autocast('cuda'):
|
| 1314 |
-
|
| 1315 |
-
|
| 1316 |
-
|
| 1317 |
-
|
| 1318 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1319 |
|
| 1320 |
# Convert predictions to numpy and denormalize using original scaler
|
| 1321 |
next_mean = next_mean.detach().cpu().numpy()
|
|
|
|
| 21 |
import warnings
|
| 22 |
import threading
|
| 23 |
from dataclasses import dataclass
|
| 24 |
+
from transformers import GenerationConfig
|
| 25 |
warnings.filterwarnings('ignore')
|
| 26 |
|
| 27 |
# Additional imports for advanced features
|
|
|
|
| 1045 |
# Convert to tensor and ensure proper shape and device
|
| 1046 |
context = torch.tensor(normalized_prices, dtype=dtype, device=device)
|
| 1047 |
|
| 1048 |
+
# Validate context data
|
| 1049 |
+
if torch.isnan(context).any() or torch.isinf(context).any():
|
| 1050 |
+
print("Warning: Context contains NaN or Inf values, replacing with zeros")
|
| 1051 |
+
context = torch.nan_to_num(context, nan=0.0, posinf=0.0, neginf=0.0)
|
| 1052 |
+
|
| 1053 |
+
# Ensure context is finite and reasonable
|
| 1054 |
+
if torch.abs(context).max() > 1000:
|
| 1055 |
+
print("Warning: Context values are very large, normalizing")
|
| 1056 |
+
context = torch.clamp(context, -1000, 1000)
|
| 1057 |
+
|
| 1058 |
+
print(f"Context validation - Shape: {context.shape}, Min: {context.min():.4f}, Max: {context.max():.4f}, Mean: {context.mean():.4f}")
|
| 1059 |
+
|
| 1060 |
# Adjust prediction length based on timeframe
|
| 1061 |
if timeframe == "1d":
|
| 1062 |
max_prediction_length = chronos_context_size # 64 days
|
|
|
|
| 1070 |
max_prediction_length = chronos_context_size # 64 intervals
|
| 1071 |
actual_prediction_length = min(prediction_days * 96, max_prediction_length)
|
| 1072 |
trim_length = prediction_days * 96
|
| 1073 |
+
|
| 1074 |
+
# Ensure prediction length is valid (must be positive and reasonable)
|
| 1075 |
+
actual_prediction_length = max(1, min(actual_prediction_length, 64))
|
| 1076 |
+
|
| 1077 |
+
print(f"Prediction length: {actual_prediction_length}")
|
| 1078 |
+
print(f"Context length: {len(context)}")
|
| 1079 |
|
| 1080 |
# Use predict_quantiles with proper formatting
|
| 1081 |
with torch.amp.autocast('cuda'):
|
| 1082 |
# Ensure all inputs are on GPU
|
| 1083 |
context = context.to(device)
|
| 1084 |
|
| 1085 |
+
# Ensure context is properly shaped and on GPU
|
| 1086 |
+
if len(context.shape) == 1:
|
| 1087 |
+
context = context.unsqueeze(0)
|
| 1088 |
+
context = context.to(device)
|
|
|
|
| 1089 |
|
| 1090 |
# Force all model components to GPU
|
| 1091 |
pipe.model = pipe.model.to(device)
|
|
|
|
| 1093 |
# Move model to evaluation mode
|
| 1094 |
pipe.model.eval()
|
| 1095 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1096 |
# Move all model parameters and buffers to GPU
|
| 1097 |
for param in pipe.model.parameters():
|
| 1098 |
param.data = param.data.to(device)
|
|
|
|
| 1170 |
# Ensure all model components are in eval mode
|
| 1171 |
pipe.model.eval()
|
| 1172 |
|
| 1173 |
+
# Fix generation configuration to prevent min_length errors
|
| 1174 |
+
if hasattr(pipe.model, 'config'):
|
| 1175 |
+
# Ensure generation config is properly set
|
| 1176 |
+
if hasattr(pipe.model.config, 'generation_config'):
|
| 1177 |
+
# Reset generation config to safe defaults
|
| 1178 |
+
pipe.model.config.generation_config.min_length = 0
|
| 1179 |
+
pipe.model.config.generation_config.max_length = 512
|
| 1180 |
+
pipe.model.config.generation_config.do_sample = False
|
| 1181 |
+
pipe.model.config.generation_config.num_beams = 1
|
| 1182 |
+
else:
|
| 1183 |
+
# Create a safe generation config if it doesn't exist
|
| 1184 |
+
pipe.model.config.generation_config = GenerationConfig(
|
| 1185 |
+
min_length=0,
|
| 1186 |
+
max_length=512,
|
| 1187 |
+
do_sample=False,
|
| 1188 |
+
num_beams=1
|
| 1189 |
+
)
|
| 1190 |
+
|
| 1191 |
# Move any additional tensors in the model's config to GPU
|
| 1192 |
if hasattr(pipe.model, 'config'):
|
| 1193 |
for key, value in pipe.model.config.__dict__.items():
|
|
|
|
| 1261 |
# Force synchronization again to ensure all tensors are on GPU
|
| 1262 |
torch.cuda.synchronize()
|
| 1263 |
|
| 1264 |
+
# Make prediction with proper parameters
|
| 1265 |
+
# Use the standard quantile levels as per Chronos documentation
|
| 1266 |
+
try:
|
| 1267 |
+
quantiles, mean = pipe.predict_quantiles(
|
| 1268 |
+
context=context,
|
| 1269 |
+
prediction_length=actual_prediction_length,
|
| 1270 |
+
quantile_levels=[0.1, 0.5, 0.9]
|
| 1271 |
+
)
|
| 1272 |
+
except Exception as prediction_error:
|
| 1273 |
+
print(f"Chronos prediction failed: {str(prediction_error)}")
|
| 1274 |
+
print(f"Context shape: {context.shape}")
|
| 1275 |
+
print(f"Context dtype: {context.dtype}")
|
| 1276 |
+
print(f"Context device: {context.device}")
|
| 1277 |
+
print(f"Prediction length: {actual_prediction_length}")
|
| 1278 |
+
print(f"Model device: {next(pipe.model.parameters()).device}")
|
| 1279 |
+
print(f"Model dtype: {next(pipe.model.parameters()).dtype}")
|
| 1280 |
+
|
| 1281 |
+
# Try with a smaller prediction length as fallback
|
| 1282 |
+
if actual_prediction_length > 1:
|
| 1283 |
+
print(f"Retrying with prediction length 1...")
|
| 1284 |
+
actual_prediction_length = 1
|
| 1285 |
+
quantiles, mean = pipe.predict_quantiles(
|
| 1286 |
+
context=context,
|
| 1287 |
+
prediction_length=actual_prediction_length,
|
| 1288 |
+
quantile_levels=[0.1, 0.5, 0.9]
|
| 1289 |
+
)
|
| 1290 |
+
else:
|
| 1291 |
+
raise prediction_error
|
| 1292 |
|
| 1293 |
if quantiles is None or mean is None or len(quantiles) == 0 or len(mean) == 0:
|
| 1294 |
raise ValueError("Chronos returned empty prediction")
|
|
|
|
| 1362 |
context = context.unsqueeze(0)
|
| 1363 |
|
| 1364 |
next_length = min(max_prediction_length, remaining_steps)
|
| 1365 |
+
# Ensure next_length is valid (must be positive and reasonable)
|
| 1366 |
+
next_length = max(1, min(next_length, 64))
|
| 1367 |
+
|
| 1368 |
with torch.amp.autocast('cuda'):
|
| 1369 |
+
try:
|
| 1370 |
+
next_quantiles, next_mean = pipe.predict_quantiles(
|
| 1371 |
+
context=context,
|
| 1372 |
+
prediction_length=next_length,
|
| 1373 |
+
quantile_levels=[0.1, 0.5, 0.9]
|
| 1374 |
+
)
|
| 1375 |
+
except Exception as extension_error:
|
| 1376 |
+
print(f"Chronos extension prediction failed: {str(extension_error)}")
|
| 1377 |
+
print(f"Extension context shape: {context.shape}")
|
| 1378 |
+
print(f"Extension prediction length: {next_length}")
|
| 1379 |
+
|
| 1380 |
+
# Try with a smaller prediction length as fallback
|
| 1381 |
+
if next_length > 1:
|
| 1382 |
+
print(f"Retrying extension with prediction length 1...")
|
| 1383 |
+
next_length = 1
|
| 1384 |
+
next_quantiles, next_mean = pipe.predict_quantiles(
|
| 1385 |
+
context=context,
|
| 1386 |
+
prediction_length=next_length,
|
| 1387 |
+
quantile_levels=[0.1, 0.5, 0.9]
|
| 1388 |
+
)
|
| 1389 |
+
else:
|
| 1390 |
+
raise extension_error
|
| 1391 |
|
| 1392 |
# Convert predictions to numpy and denormalize using original scaler
|
| 1393 |
next_mean = next_mean.detach().cpu().numpy()
|