Instructions to use hchen657Naza/PWM with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use hchen657Naza/PWM with Diffusers:
pip install -U diffusers transformers accelerate
import torch from diffusers import DiffusionPipeline # switch to "mps" for apple devices pipe = DiffusionPipeline.from_pretrained("hchen657Naza/PWM", dtype=torch.bfloat16, device_map="cuda") prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" image = pipe(prompt).images[0] - Notebooks
- Google Colab
- Kaggle
Download PWM_code/reward_model/robometer/scripts/robometer_wrapper.py from hchen657Naza/PWM: direct link, hf CLI and curl.
- Browser
- Download file 5.9 kB
-
https://huggingface.co/hchen657Naza/PWM/resolve/main/PWM_code/reward_model/robometer/scripts/robometer_wrapper.py
- Command line
-
hf download hf://hchen657Naza/PWM/PWM_code/reward_model/robometer/scripts/robometer_wrapper.py
-
curl -L -o robometer_wrapper.py https://huggingface.co/hchen657Naza/PWM/resolve/main/PWM_code/reward_model/robometer/scripts/robometer_wrapper.py
5.9 kB
| #!/usr/bin/env python3 | |
| """Minimal Robometer wrapper that resizes frames to fit in memory.""" | |
| from __future__ import annotations | |
| import argparse | |
| import os | |
| from pathlib import Path | |
| from typing import Optional, Tuple | |
| import numpy as np | |
| import torch | |
| import cv2 | |
| # Must import unsloth first | |
| import unsloth # noqa | |
| from robometer.data.dataset_types import ProgressSample, Trajectory | |
| from robometer.evals.eval_server import compute_batch_outputs | |
| from robometer.evals.eval_viz_utils import extract_frames | |
| from robometer.utils.save import load_model_from_hf | |
| from robometer.utils.setup_utils import setup_batch_collator | |
| def resize_frames(frames: np.ndarray, max_side: int = 256) -> np.ndarray: | |
| """Resize frames so max side = max_side.""" | |
| T, H, W, C = frames.shape | |
| scale = max_side / max(H, W) | |
| if scale < 1: | |
| new_h = (int(H * scale) // 28) * 28 # must be multiple of 28 for qwen-vl | |
| new_w = (int(W * scale) // 28) * 28 | |
| out = np.zeros((T, new_h, new_w, C), dtype=np.uint8) | |
| for i in range(T): | |
| out[i] = cv2.resize(frames[i], (new_w, new_h), interpolation=cv2.INTER_AREA) | |
| return out | |
| return frames | |
| _CACHED_MODEL = None | |
| def load_robometer_once(model_path: str = "robometer/Robometer-4B", device: str = "cuda"): | |
| """Load model once globally.""" | |
| global _CACHED_MODEL | |
| if _CACHED_MODEL is None: | |
| device = torch.device(device) | |
| exp_config, tokenizer, processor, reward_model = load_model_from_hf( | |
| model_path=model_path, device=device, | |
| ) | |
| reward_model.eval() | |
| batch_collator = setup_batch_collator(processor, tokenizer, exp_config, is_eval=True) | |
| _CACHED_MODEL = dict( | |
| model=reward_model, tokenizer=tokenizer, processor=processor, | |
| batch_collator=batch_collator, exp_config=exp_config, device=device, | |
| ) | |
| return _CACHED_MODEL | |
| def compute_rewards( | |
| video_frames: np.ndarray, | |
| task: str, | |
| max_side: int = 256, | |
| state: Optional[dict] = None, | |
| ) -> Tuple[np.ndarray, np.ndarray]: | |
| """ | |
| Compute per-frame progress and success probability. | |
| Args: | |
| video_frames: (T, H, W, C) uint8 | |
| task: task instruction string | |
| max_side: resize frames so max dim = max_side | |
| Returns: | |
| (progress, success): both arrays of length T | |
| """ | |
| if state is None: | |
| state = load_robometer_once() | |
| frames = resize_frames(video_frames, max_side=max_side) | |
| T = int(frames.shape[0]) | |
| traj = Trajectory( | |
| frames=frames, | |
| frames_shape=tuple(frames.shape), | |
| task=task, | |
| id="0", | |
| metadata={"subsequence_length": T}, | |
| video_embeddings=None, | |
| ) | |
| progress_sample = ProgressSample(trajectory=traj, sample_type="progress") | |
| batch = state["batch_collator"]([progress_sample]) | |
| progress_inputs = batch["progress_inputs"] | |
| for key, value in progress_inputs.items(): | |
| if hasattr(value, "to"): | |
| progress_inputs[key] = value.to(state["device"]) | |
| loss_config = getattr(state["exp_config"], "loss", None) | |
| is_discrete = ( | |
| getattr(loss_config, "progress_loss_type", "l2").lower() == "discrete" | |
| if loss_config else False | |
| ) | |
| num_bins = ( | |
| getattr(loss_config, "progress_discrete_bins", None) | |
| or getattr(state["exp_config"].model, "progress_discrete_bins", 10) | |
| ) | |
| with torch.inference_mode(): | |
| results = compute_batch_outputs( | |
| state["model"], state["tokenizer"], progress_inputs, | |
| sample_type="progress", is_discrete_mode=is_discrete, num_bins=num_bins, | |
| ) | |
| progress_pred = results.get("progress_pred", []) | |
| progress_array = ( | |
| np.array(progress_pred[0], dtype=np.float32) | |
| if progress_pred and len(progress_pred) > 0 | |
| else np.array([], dtype=np.float32) | |
| ) | |
| outputs_success = results.get("outputs_success", {}) | |
| success_probs = outputs_success.get("success_probs", []) if outputs_success else [] | |
| success_array = ( | |
| np.array(success_probs[0], dtype=np.float32) | |
| if success_probs and len(success_probs) > 0 | |
| else np.array([], dtype=np.float32) | |
| ) | |
| return progress_array, success_array | |
| def score_video_file( | |
| video_path: str, | |
| task: str, | |
| fps: float = 3.0, | |
| max_frames: int = 8, | |
| max_side: int = 256, | |
| state: Optional[dict] = None, | |
| ) -> Tuple[np.ndarray, np.ndarray]: | |
| frames = extract_frames(video_path, fps=fps, max_frames=max_frames) | |
| if frames is None or frames.size == 0: | |
| raise RuntimeError(f"Could not extract frames from {video_path}") | |
| return compute_rewards(frames, task, max_side=max_side, state=state) | |
| if __name__ == "__main__": | |
| p = argparse.ArgumentParser() | |
| p.add_argument("--video", required=True) | |
| p.add_argument("--task", required=True) | |
| p.add_argument("--model-path", default="robometer/Robometer-4B") | |
| p.add_argument("--fps", type=float, default=3.0) | |
| p.add_argument("--max-frames", type=int, default=8) | |
| p.add_argument("--max-side", type=int, default=256) | |
| p.add_argument("--out", default="/tmp/robometer_out") | |
| args = p.parse_args() | |
| print(f"Loading model from {args.model_path}...") | |
| state = load_robometer_once(args.model_path) | |
| print(f"Scoring video: {args.video}") | |
| progress, success = score_video_file( | |
| args.video, args.task, | |
| fps=args.fps, max_frames=args.max_frames, max_side=args.max_side, | |
| state=state, | |
| ) | |
| Path(args.out).mkdir(parents=True, exist_ok=True) | |
| np.save(os.path.join(args.out, "progress.npy"), progress) | |
| np.save(os.path.join(args.out, "success.npy"), success) | |
| print(f"Progress: shape={progress.shape}, values={progress.tolist()}") | |
| print(f"Success: shape={success.shape}, values={success.tolist()}") | |
| print(f"Mean progress: {float(np.mean(progress)):.3f}") | |
| print(f"Mean success: {float(np.mean(success)):.3f}") | |