ojaffe commited on
Commit
da157ad
·
verified ·
1 Parent(s): 613565a

Upload folder using huggingface_hub

Browse files
Files changed (2) hide show
  1. __pycache__/predict.cpython-311.pyc +0 -0
  2. predict.py +27 -20
__pycache__/predict.cpython-311.pyc CHANGED
Binary files a/__pycache__/predict.cpython-311.pyc and b/__pycache__/predict.cpython-311.pyc differ
 
predict.py CHANGED
@@ -1,4 +1,4 @@
1
- """Inference tricks: Pong AR caching, Sonic step-dependent blending."""
2
  import sys
3
  import os
4
  import numpy as np
@@ -42,7 +42,6 @@ class EnsembleModels:
42
  def load_model(model_dir: str):
43
  ens = EnsembleModels()
44
 
45
- # Pong: full AR model (3 outputs)
46
  pong = UNet(in_channels=24, out_channels=3,
47
  enc_channels=(32, 64, 128), bottleneck_channels=128,
48
  upsample_mode="bilinear").to(DEVICE)
@@ -52,7 +51,6 @@ def load_model(model_dir: str):
52
  pong.eval()
53
  ens.models["pong"] = pong
54
 
55
- # Sonic AR model (3 outputs)
56
  sonic_ar = UNet(in_channels=24, out_channels=3,
57
  enc_channels=(48, 96, 192), bottleneck_channels=256,
58
  upsample_mode="bilinear").to(DEVICE)
@@ -62,7 +60,6 @@ def load_model(model_dir: str):
62
  sonic_ar.eval()
63
  ens.sonic_ar = sonic_ar
64
 
65
- # Sonic direct model (24 outputs)
66
  sonic_direct = UNet(in_channels=24, out_channels=24,
67
  enc_channels=(48, 96, 192), bottleneck_channels=256,
68
  upsample_mode="bilinear").to(DEVICE)
@@ -72,7 +69,6 @@ def load_model(model_dir: str):
72
  sonic_direct.eval()
73
  ens.sonic_direct = sonic_direct
74
 
75
- # PP: compact direct 8-frame model (24 outputs)
76
  pp = UNet(in_channels=24, out_channels=24,
77
  enc_channels=(24, 48, 96), bottleneck_channels=128,
78
  upsample_mode="bilinear").to(DEVICE)
@@ -115,7 +111,7 @@ def predict_next_frame(ens, context_frames: np.ndarray) -> np.ndarray:
115
  last_frame_t = np.transpose(last_frame, (2, 0, 1))[np.newaxis]
116
 
117
  if game == "pong":
118
- # Pong: AR with internal caching (all 8 steps in float32)
119
  if ens.direct_cache is not None and n > CONTEXT_FRAMES and ens.cache_step < PRED_FRAMES:
120
  result = ens.direct_cache[ens.cache_step]
121
  ens.cache_step += 1
@@ -129,22 +125,36 @@ def predict_next_frame(ens, context_frames: np.ndarray) -> np.ndarray:
129
  context_tensor = torch.from_numpy(context).to(DEVICE)
130
  last_tensor = torch.from_numpy(last_frame_t).to(DEVICE)
131
 
132
- # Run all 8 AR steps in float32 (no uint8 quantization between steps)
133
- preds = []
134
  ctx = context_tensor.clone()
135
  last_t = last_tensor.clone()
136
  for step in range(PRED_FRAMES):
137
  predicted = _predict_ar_frame(model, ctx, last_t)
138
- preds.append(predicted)
139
- # Shift context with float32 prediction (no quantization)
140
  ctx_frames = ctx.reshape(1, CONTEXT_FRAMES, 3, 64, 64)
141
  ctx_frames = torch.cat([ctx_frames[:, 1:], predicted.unsqueeze(1)], dim=1)
142
  ctx = ctx_frames.reshape(1, -1, 64, 64)
143
  last_t = predicted
144
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  ens.direct_cache = []
146
  for i in range(PRED_FRAMES):
147
- frame = preds[i][0].cpu().numpy()
 
148
  frame = np.transpose(frame, (1, 2, 0))
149
  frame = (frame * 255).clip(0, 255).astype(np.uint8)
150
  ens.direct_cache.append(frame)
@@ -154,7 +164,7 @@ def predict_next_frame(ens, context_frames: np.ndarray) -> np.ndarray:
154
  return result
155
 
156
  elif game == "sonic":
157
- # Sonic: step-dependent AR/direct blending with caching
158
  if ens.direct_cache is not None and n > CONTEXT_FRAMES and ens.cache_step < PRED_FRAMES:
159
  result = ens.direct_cache[ens.cache_step]
160
  ens.cache_step += 1
@@ -167,15 +177,13 @@ def predict_next_frame(ens, context_frames: np.ndarray) -> np.ndarray:
167
  context_tensor = torch.from_numpy(context).to(DEVICE)
168
  last_tensor = torch.from_numpy(last_frame_t).to(DEVICE)
169
 
170
- # Direct prediction with TTA
171
  direct_orig = _predict_8frames_direct(ens.sonic_direct, context_tensor, last_tensor)
172
  context_flipped = torch.flip(context_tensor, dims=[3])
173
  last_flipped = torch.flip(last_tensor, dims=[3])
174
  direct_flipped = _predict_8frames_direct(ens.sonic_direct, context_flipped, last_flipped)
175
  direct_flipped = torch.flip(direct_flipped, dims=[4])
176
- direct_pred = (direct_orig + direct_flipped) / 2.0 # (1, 8, 3, 64, 64)
177
 
178
- # AR prediction with TTA
179
  ar_preds = []
180
  ctx = context_tensor.clone()
181
  ctx_flip = context_flipped.clone()
@@ -196,14 +204,13 @@ def predict_next_frame(ens, context_frames: np.ndarray) -> np.ndarray:
196
  ctx_flip = ctx_flip_frames.reshape(1, -1, 64, 64)
197
  last_f = ar_flip
198
 
199
- ar_pred = torch.stack(ar_preds, dim=1) # (1, 8, 3, 64, 64)
200
 
201
- # Step-dependent blending: AR weight goes from 0.7 (step 0) to 0.3 (step 7)
202
- # Direct weight goes from 0.3 (step 0) to 0.7 (step 7)
203
  predicted = torch.zeros_like(direct_pred)
204
  for step in range(PRED_FRAMES):
205
- ar_weight = 0.7 - (step / (PRED_FRAMES - 1)) * 0.4 # 0.7 -> 0.3
206
- direct_weight = 1.0 - ar_weight # 0.3 -> 0.7
207
  predicted[:, step] = ar_weight * ar_pred[:, step] + direct_weight * direct_pred[:, step]
208
 
209
  predicted_np = predicted[0].cpu().numpy()
 
1
+ """Inference v2: Pong AR+TTA caching, Sonic aggressive blending."""
2
  import sys
3
  import os
4
  import numpy as np
 
42
  def load_model(model_dir: str):
43
  ens = EnsembleModels()
44
 
 
45
  pong = UNet(in_channels=24, out_channels=3,
46
  enc_channels=(32, 64, 128), bottleneck_channels=128,
47
  upsample_mode="bilinear").to(DEVICE)
 
51
  pong.eval()
52
  ens.models["pong"] = pong
53
 
 
54
  sonic_ar = UNet(in_channels=24, out_channels=3,
55
  enc_channels=(48, 96, 192), bottleneck_channels=256,
56
  upsample_mode="bilinear").to(DEVICE)
 
60
  sonic_ar.eval()
61
  ens.sonic_ar = sonic_ar
62
 
 
63
  sonic_direct = UNet(in_channels=24, out_channels=24,
64
  enc_channels=(48, 96, 192), bottleneck_channels=256,
65
  upsample_mode="bilinear").to(DEVICE)
 
69
  sonic_direct.eval()
70
  ens.sonic_direct = sonic_direct
71
 
 
72
  pp = UNet(in_channels=24, out_channels=24,
73
  enc_channels=(24, 48, 96), bottleneck_channels=128,
74
  upsample_mode="bilinear").to(DEVICE)
 
111
  last_frame_t = np.transpose(last_frame, (2, 0, 1))[np.newaxis]
112
 
113
  if game == "pong":
114
+ # Pong: AR with TTA and internal float32 caching
115
  if ens.direct_cache is not None and n > CONTEXT_FRAMES and ens.cache_step < PRED_FRAMES:
116
  result = ens.direct_cache[ens.cache_step]
117
  ens.cache_step += 1
 
125
  context_tensor = torch.from_numpy(context).to(DEVICE)
126
  last_tensor = torch.from_numpy(last_frame_t).to(DEVICE)
127
 
128
+ # Original AR
129
+ preds_orig = []
130
  ctx = context_tensor.clone()
131
  last_t = last_tensor.clone()
132
  for step in range(PRED_FRAMES):
133
  predicted = _predict_ar_frame(model, ctx, last_t)
134
+ preds_orig.append(predicted)
 
135
  ctx_frames = ctx.reshape(1, CONTEXT_FRAMES, 3, 64, 64)
136
  ctx_frames = torch.cat([ctx_frames[:, 1:], predicted.unsqueeze(1)], dim=1)
137
  ctx = ctx_frames.reshape(1, -1, 64, 64)
138
  last_t = predicted
139
 
140
+ # TTA: horizontal flip AR
141
+ context_flipped = torch.flip(context_tensor, dims=[3])
142
+ last_flipped = torch.flip(last_tensor, dims=[3])
143
+ preds_flip = []
144
+ ctx_f = context_flipped.clone()
145
+ last_f = last_flipped.clone()
146
+ for step in range(PRED_FRAMES):
147
+ predicted_f = _predict_ar_frame(model, ctx_f, last_f)
148
+ preds_flip.append(torch.flip(predicted_f, dims=[3])) # flip back
149
+ ctx_frames_f = ctx_f.reshape(1, CONTEXT_FRAMES, 3, 64, 64)
150
+ ctx_frames_f = torch.cat([ctx_frames_f[:, 1:], predicted_f.unsqueeze(1)], dim=1)
151
+ ctx_f = ctx_frames_f.reshape(1, -1, 64, 64)
152
+ last_f = predicted_f
153
+
154
  ens.direct_cache = []
155
  for i in range(PRED_FRAMES):
156
+ avg = (preds_orig[i] + preds_flip[i]) / 2.0
157
+ frame = avg[0].cpu().numpy()
158
  frame = np.transpose(frame, (1, 2, 0))
159
  frame = (frame * 255).clip(0, 255).astype(np.uint8)
160
  ens.direct_cache.append(frame)
 
164
  return result
165
 
166
  elif game == "sonic":
167
+ # Sonic: step-dependent blending with more aggressive shift to direct
168
  if ens.direct_cache is not None and n > CONTEXT_FRAMES and ens.cache_step < PRED_FRAMES:
169
  result = ens.direct_cache[ens.cache_step]
170
  ens.cache_step += 1
 
177
  context_tensor = torch.from_numpy(context).to(DEVICE)
178
  last_tensor = torch.from_numpy(last_frame_t).to(DEVICE)
179
 
 
180
  direct_orig = _predict_8frames_direct(ens.sonic_direct, context_tensor, last_tensor)
181
  context_flipped = torch.flip(context_tensor, dims=[3])
182
  last_flipped = torch.flip(last_tensor, dims=[3])
183
  direct_flipped = _predict_8frames_direct(ens.sonic_direct, context_flipped, last_flipped)
184
  direct_flipped = torch.flip(direct_flipped, dims=[4])
185
+ direct_pred = (direct_orig + direct_flipped) / 2.0
186
 
 
187
  ar_preds = []
188
  ctx = context_tensor.clone()
189
  ctx_flip = context_flipped.clone()
 
204
  ctx_flip = ctx_flip_frames.reshape(1, -1, 64, 64)
205
  last_f = ar_flip
206
 
207
+ ar_pred = torch.stack(ar_preds, dim=1)
208
 
209
+ # More aggressive blending: AR weight 0.8 -> 0.2
 
210
  predicted = torch.zeros_like(direct_pred)
211
  for step in range(PRED_FRAMES):
212
+ ar_weight = 0.8 - (step / (PRED_FRAMES - 1)) * 0.6 # 0.8 -> 0.2
213
+ direct_weight = 1.0 - ar_weight
214
  predicted[:, step] = ar_weight * ar_pred[:, step] + direct_weight * direct_pred[:, step]
215
 
216
  predicted_np = predicted[0].cpu().numpy()