ojaffe commited on
Commit
08d4e40
·
verified ·
1 Parent(s): da157ad

Upload folder using huggingface_hub

Browse files
__pycache__/predict.cpython-311.pyc CHANGED
Binary files a/__pycache__/predict.cpython-311.pyc and b/__pycache__/predict.cpython-311.pyc differ
 
model_pong_direct.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ab8070ddcde00333d7b52c89a0da9a61eece1e67c46163cd011ce4cd3c422f0c
3
+ size 2436712
predict.py CHANGED
@@ -1,4 +1,4 @@
1
- """Inference v2: Pong AR+TTA caching, Sonic aggressive blending."""
2
  import sys
3
  import os
4
  import numpy as np
@@ -31,6 +31,7 @@ class EnsembleModels:
31
  self.models = {}
32
  self.sonic_ar = None
33
  self.sonic_direct = None
 
34
  self.direct_cache = None
35
  self.cache_step = 0
36
 
@@ -42,6 +43,7 @@ class EnsembleModels:
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,6 +53,17 @@ def load_model(model_dir: str):
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,6 +73,7 @@ def load_model(model_dir: str):
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,6 +83,7 @@ def load_model(model_dir: str):
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,7 +126,7 @@ def predict_next_frame(ens, context_frames: np.ndarray) -> np.ndarray:
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
@@ -120,42 +135,40 @@ def predict_next_frame(ens, context_frames: np.ndarray) -> np.ndarray:
120
  return result
121
 
122
  ens.reset_cache()
123
- model = ens.models["pong"]
 
124
  with torch.no_grad():
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)
161
 
@@ -164,7 +177,7 @@ def predict_next_frame(ens, context_frames: np.ndarray) -> np.ndarray:
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
@@ -206,10 +219,9 @@ def predict_next_frame(ens, context_frames: np.ndarray) -> np.ndarray:
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
 
@@ -225,7 +237,7 @@ def predict_next_frame(ens, context_frames: np.ndarray) -> np.ndarray:
225
  return result
226
 
227
  else:
228
- # PP: direct 8-frame with caching and TTA
229
  if ens.direct_cache is not None and n > CONTEXT_FRAMES and ens.cache_step < PRED_FRAMES:
230
  result = ens.direct_cache[ens.cache_step]
231
  ens.cache_step += 1
 
1
+ """FP16 Pong ensemble: AR+direct for Pong, AR+direct for Sonic, direct for PP."""
2
  import sys
3
  import os
4
  import numpy as np
 
31
  self.models = {}
32
  self.sonic_ar = None
33
  self.sonic_direct = None
34
+ self.pong_direct = None
35
  self.direct_cache = None
36
  self.cache_step = 0
37
 
 
43
  def load_model(model_dir: str):
44
  ens = EnsembleModels()
45
 
46
+ # Pong AR (3 outputs)
47
  pong = UNet(in_channels=24, out_channels=3,
48
  enc_channels=(32, 64, 128), bottleneck_channels=128,
49
  upsample_mode="bilinear").to(DEVICE)
 
53
  pong.eval()
54
  ens.models["pong"] = pong
55
 
56
+ # Pong direct (24 outputs)
57
+ pong_direct = UNet(in_channels=24, out_channels=24,
58
+ enc_channels=(32, 64, 128), bottleneck_channels=128,
59
+ upsample_mode="bilinear").to(DEVICE)
60
+ sd = torch.load(os.path.join(model_dir, "model_pong_direct.pt"),
61
+ map_location=DEVICE, weights_only=True)
62
+ pong_direct.load_state_dict({k: v.float() for k, v in sd.items()})
63
+ pong_direct.eval()
64
+ ens.pong_direct = pong_direct
65
+
66
+ # Sonic AR (3 outputs)
67
  sonic_ar = UNet(in_channels=24, out_channels=3,
68
  enc_channels=(48, 96, 192), bottleneck_channels=256,
69
  upsample_mode="bilinear").to(DEVICE)
 
73
  sonic_ar.eval()
74
  ens.sonic_ar = sonic_ar
75
 
76
+ # Sonic direct (24 outputs)
77
  sonic_direct = UNet(in_channels=24, out_channels=24,
78
  enc_channels=(48, 96, 192), bottleneck_channels=256,
79
  upsample_mode="bilinear").to(DEVICE)
 
83
  sonic_direct.eval()
84
  ens.sonic_direct = sonic_direct
85
 
86
+ # PP compact direct (24 outputs)
87
  pp = UNet(in_channels=24, out_channels=24,
88
  enc_channels=(24, 48, 96), bottleneck_channels=128,
89
  upsample_mode="bilinear").to(DEVICE)
 
126
  last_frame_t = np.transpose(last_frame, (2, 0, 1))[np.newaxis]
127
 
128
  if game == "pong":
129
+ # Pong: AR+direct ensemble with float32 caching, no TTA
130
  if ens.direct_cache is not None and n > CONTEXT_FRAMES and ens.cache_step < PRED_FRAMES:
131
  result = ens.direct_cache[ens.cache_step]
132
  ens.cache_step += 1
 
135
  return result
136
 
137
  ens.reset_cache()
138
+ model_ar = ens.models["pong"]
139
+ model_direct = ens.pong_direct
140
  with torch.no_grad():
141
  context_tensor = torch.from_numpy(context).to(DEVICE)
142
  last_tensor = torch.from_numpy(last_frame_t).to(DEVICE)
143
 
144
+ # Direct prediction
145
+ direct_pred = _predict_8frames_direct(model_direct, context_tensor, last_tensor)
146
+
147
+ # AR prediction in float32
148
+ ar_preds = []
149
  ctx = context_tensor.clone()
150
  last_t = last_tensor.clone()
151
  for step in range(PRED_FRAMES):
152
+ predicted = _predict_ar_frame(model_ar, ctx, last_t)
153
+ ar_preds.append(predicted)
154
  ctx_frames = ctx.reshape(1, CONTEXT_FRAMES, 3, 64, 64)
155
  ctx_frames = torch.cat([ctx_frames[:, 1:], predicted.unsqueeze(1)], dim=1)
156
  ctx = ctx_frames.reshape(1, -1, 64, 64)
157
  last_t = predicted
158
 
159
+ ar_pred = torch.stack(ar_preds, dim=1)
160
+
161
+ # Step-dependent blending: AR 0.7 -> 0.3
162
+ predicted = torch.zeros_like(direct_pred)
 
 
163
  for step in range(PRED_FRAMES):
164
+ ar_weight = 0.7 - (step / (PRED_FRAMES - 1)) * 0.4
165
+ direct_weight = 1.0 - ar_weight
166
+ predicted[:, step] = ar_weight * ar_pred[:, step] + direct_weight * direct_pred[:, step]
 
 
 
167
 
168
+ predicted_np = predicted[0].cpu().numpy()
169
  ens.direct_cache = []
170
  for i in range(PRED_FRAMES):
171
+ frame = np.transpose(predicted_np[i], (1, 2, 0))
 
 
172
  frame = (frame * 255).clip(0, 255).astype(np.uint8)
173
  ens.direct_cache.append(frame)
174
 
 
177
  return result
178
 
179
  elif game == "sonic":
180
+ # Sonic: AR+direct with step blending and TTA
181
  if ens.direct_cache is not None and n > CONTEXT_FRAMES and ens.cache_step < PRED_FRAMES:
182
  result = ens.direct_cache[ens.cache_step]
183
  ens.cache_step += 1
 
219
 
220
  ar_pred = torch.stack(ar_preds, dim=1)
221
 
 
222
  predicted = torch.zeros_like(direct_pred)
223
  for step in range(PRED_FRAMES):
224
+ ar_weight = 0.7 - (step / (PRED_FRAMES - 1)) * 0.4
225
  direct_weight = 1.0 - ar_weight
226
  predicted[:, step] = ar_weight * ar_pred[:, step] + direct_weight * direct_pred[:, step]
227
 
 
237
  return result
238
 
239
  else:
240
+ # PP: direct with TTA and caching
241
  if ens.direct_cache is not None and n > CONTEXT_FRAMES and ens.cache_step < PRED_FRAMES:
242
  result = ens.direct_cache[ens.cache_step]
243
  ens.cache_step += 1