Spaces:
Sleeping
Sleeping
File size: 6,412 Bytes
93b20f5 259de4c 93b20f5 df613f6 93b20f5 259de4c 93b20f5 df613f6 93b20f5 df613f6 93b20f5 df613f6 93b20f5 259de4c 93b20f5 df613f6 93b20f5 df613f6 93b20f5 259de4c 93b20f5 259de4c 93b20f5 df613f6 93b20f5 259de4c 93b20f5 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | """Hugging Face Gradio Space for state-conditioned π₀.₅ UR inference."""
from __future__ import annotations
import gc
try:
import gradio as gr
except ImportError: # Core inference tests can run without the UI dependency.
gr = None
try:
import spaces
except ImportError: # Local and dedicated-GPU environments omit this helper.
class _SpacesFallback:
@staticmethod
def GPU(*args, **kwargs):
return lambda function: function
spaces = _SpacesFallback()
from artifacts import download_checkpoint, resolve_checkpoint_path, resolve_model_id
from inference import ACTION_LABELS, run_prediction
from model_loader import DEFAULT_POLICY_CONFIG, MODEL_MANAGER, POLICY_CONFIGS
def prefetch_configured_checkpoint() -> str:
"""Download and validate configured weights during Space startup, before GPU use."""
model_id = resolve_model_id()
if not model_id:
return "No PI05_MODEL_ID configured; download will occur on first prediction."
checkpoint_path = resolve_checkpoint_path()
paths = download_checkpoint(model_id, checkpoint_path)
return f"Checkpoint ready: {model_id}/{checkpoint_path} ({paths.norm_stats.name})."
def _gradio_integer(value, name: str) -> int:
if isinstance(value, bool) or not isinstance(value, (int, float)):
raise ValueError(f"{name} must be an integer")
if not float(value).is_integer():
raise ValueError(f"{name} must be an integer")
result = int(value)
if result < 0:
raise ValueError(f"{name} must be non-negative")
return result
@spaces.GPU(duration=120)
def predict_ui(
model_id,
checkpoint_path,
config_name,
fixed_image,
wrist_image,
instruction,
tcp_x,
tcp_y,
tcp_z,
tcp_roll,
tcp_pitch,
tcp_yaw,
gripper,
trial_index,
):
try:
trial = _gradio_integer(trial_index, "trial index")
policy = MODEL_MANAGER.get(model_id, checkpoint_path, config_name)
result = run_prediction(
policy,
fixed_image,
wrist_image,
instruction,
[tcp_x, tcp_y, tcp_z, tcp_roll, tcp_pitch, tcp_yaw, gripper],
trial,
model_id,
checkpoint_path,
)
uses_discrete_state = config_name == "pi05_ur_demo_state"
status = (
f"{result.status} Config={config_name} "
f"(discrete_state_input={uses_discrete_state})."
)
return result.actions, result.json_path, status
except Exception as exc:
gc.collect()
try:
import torch
if torch.cuda.is_available():
torch.cuda.empty_cache()
except ImportError:
pass
return None, None, f"Error: {exc}"
def build_demo():
if gr is None:
return None
with gr.Blocks(title="π₀.₅ UR Action Predictor") as demo:
gr.Markdown(
"# π₀.₅ UR Action Predictor\n"
"forked from , thx!"
"Upload the fixed and wrist camera views, enter the current TCP/gripper "
"state and a task instruction. This demo predicts actions only and does "
"not directly control a robot."
)
with gr.Row():
model_id = gr.Textbox(
value=resolve_model_id(),
label="Hugging Face model ID",
placeholder="owner/pi05-ur-checkpoint",
)
checkpoint_path = gr.Textbox(
value=resolve_checkpoint_path(),
label="Checkpoint path",
placeholder="checkpoints/30000",
)
config_name = gr.Dropdown(
choices=list(POLICY_CONFIGS),
value=DEFAULT_POLICY_CONFIG,
label="Policy config",
)
with gr.Row():
fixed_image = gr.Image(type="pil", label="Fixed camera")
wrist_image = gr.Image(type="pil", label="Wrist camera")
instruction = gr.Textbox(
label="Task instruction",
placeholder="e.g. pick up the object and place it in the tray",
lines=2,
)
gr.Markdown(
"### Current state — metres/radians, followed by gripper state\n"
"These values are discrete state conditioning only when "
"`pi05_ur_demo_state` is selected."
)
with gr.Row():
tcp_x = gr.Number(value=0.0, label="TCP x")
tcp_y = gr.Number(value=0.0, label="TCP y")
tcp_z = gr.Number(value=0.0, label="TCP z")
tcp_roll = gr.Number(value=0.0, label="TCP roll")
gr.Markdown("哈基米")
with gr.Row():
tcp_pitch = gr.Number(value=0.0, label="TCP pitch")
tcp_yaw = gr.Number(value=0.0, label="TCP yaw")
gripper = gr.Number(value=0.0, label="Gripper")
trial_index = gr.Number(value=0, precision=0, minimum=0, label="Trial index")
predict_button = gr.Button("Predict actions", variant="primary")
status = gr.Markdown(STARTUP_STATUS)
actions = gr.Dataframe(headers=list(ACTION_LABELS), interactive=False, label="Predicted actions")
json_output = gr.File(label="Download JSON result")
predict_button.click(
fn=predict_ui,
inputs=[
model_id,
checkpoint_path,
config_name,
fixed_image,
wrist_image,
instruction,
tcp_x,
tcp_y,
tcp_z,
tcp_roll,
tcp_pitch,
tcp_yaw,
gripper,
trial_index,
],
outputs=[actions, json_output, status],
)
return demo
# Hugging Face Spaces imports app.py during startup. Prefetching here moves the
# multi-GB download out of the GPU-decorated prediction request when env vars are set.
try:
STARTUP_STATUS = prefetch_configured_checkpoint()
except Exception as exc:
STARTUP_STATUS = f"Checkpoint prefetch deferred: {exc}"
demo = build_demo()
if __name__ == "__main__":
if demo is None:
raise RuntimeError("Gradio is not installed; install requirements.txt first")
demo.queue(default_concurrency_limit=1).launch()
|