Upload folder using huggingface_hub
Browse files- graders/aggregate.py +2 -2
- inference.py +124 -44
- server/my_env_environment.py +1 -1
graders/aggregate.py
CHANGED
|
@@ -88,7 +88,7 @@ class AggregateGrader:
|
|
| 88 |
"(fid=%.4f eff=%.4f noise=%.4f cstr=%.4f)",
|
| 89 |
fidelity_score, efficiency_score, noise_score, constraints_score,
|
| 90 |
)
|
| 91 |
-
return 0.
|
| 92 |
|
| 93 |
# Weighted sum
|
| 94 |
weighted_sum = (
|
|
@@ -102,7 +102,7 @@ class AggregateGrader:
|
|
| 102 |
# cannot score highly from efficiency/noise alone.
|
| 103 |
aggregate = weighted_sum * fidelity_score
|
| 104 |
|
| 105 |
-
aggregate = float(max(0.
|
| 106 |
|
| 107 |
logger.debug(
|
| 108 |
"Aggregate: %.4f (fid=%.4f eff=%.4f noise=%.4f cstr=%.4f, "
|
|
|
|
| 88 |
"(fid=%.4f eff=%.4f noise=%.4f cstr=%.4f)",
|
| 89 |
fidelity_score, efficiency_score, noise_score, constraints_score,
|
| 90 |
)
|
| 91 |
+
return 0.0001
|
| 92 |
|
| 93 |
# Weighted sum
|
| 94 |
weighted_sum = (
|
|
|
|
| 102 |
# cannot score highly from efficiency/noise alone.
|
| 103 |
aggregate = weighted_sum * fidelity_score
|
| 104 |
|
| 105 |
+
aggregate = float(max(0.0001, min(0.9999, aggregate)))
|
| 106 |
|
| 107 |
logger.debug(
|
| 108 |
"Aggregate: %.4f (fid=%.4f eff=%.4f noise=%.4f cstr=%.4f, "
|
inference.py
CHANGED
|
@@ -99,56 +99,136 @@ def log_end(success: bool, steps: int, score: float, rewards: List[float]) -> No
|
|
| 99 |
# System prompt for the LLM
|
| 100 |
# ---------------------------------------------------------------------------
|
| 101 |
|
| 102 |
-
SYSTEM_PROMPT = textwrap.dedent("""
|
| 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 |
# LLM interaction
|
| 132 |
# ---------------------------------------------------------------------------
|
| 133 |
|
| 134 |
def build_user_prompt(obs_data: Dict[str, Any], step: int, history: List[str]) -> str:
|
| 135 |
-
"""
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 152 |
""")
|
| 153 |
|
| 154 |
|
|
@@ -288,7 +368,7 @@ async def run_task(
|
|
| 288 |
|
| 289 |
# Final score = aggregate score from the environment
|
| 290 |
score = obs_data.get("score", 0.0)
|
| 291 |
-
score = min(max(score, 0.
|
| 292 |
success = obs_data.get("fidelity", 0.0) >= SUCCESS_FIDELITY
|
| 293 |
|
| 294 |
finally:
|
|
|
|
| 99 |
# System prompt for the LLM
|
| 100 |
# ---------------------------------------------------------------------------
|
| 101 |
|
| 102 |
+
SYSTEM_PROMPT = textwrap.dedent("""
|
| 103 |
+
You are an expert quantum circuit optimization agent.
|
| 104 |
+
|
| 105 |
+
You are NOT a pattern generator.
|
| 106 |
+
You MUST behave as a decision-making optimizer that improves the circuit step-by-step.
|
| 107 |
+
|
| 108 |
+
Your goal:
|
| 109 |
+
Maximize fidelity to the target while minimizing circuit depth and noise impact.
|
| 110 |
+
|
| 111 |
+
---
|
| 112 |
+
|
| 113 |
+
AVAILABLE ACTIONS (respond with valid JSON only):
|
| 114 |
+
|
| 115 |
+
1. ADD:
|
| 116 |
+
{"action_type": "ADD", "gate": "<H|X|CNOT|RX|RZ>", "qubits": [<int>, ...], "parameter": <float or null>}
|
| 117 |
+
|
| 118 |
+
2. REMOVE:
|
| 119 |
+
{"action_type": "REMOVE", "qubits": []}
|
| 120 |
+
|
| 121 |
+
3. SWAP:
|
| 122 |
+
{"action_type": "SWAP", "qubits": [q1, q2]}
|
| 123 |
+
|
| 124 |
+
4. PARAM:
|
| 125 |
+
{"action_type": "PARAM", "qubits": [], "parameter": <float>}
|
| 126 |
+
|
| 127 |
+
5. STOP:
|
| 128 |
+
{"action_type": "STOP", "qubits": []}
|
| 129 |
+
|
| 130 |
+
---
|
| 131 |
+
|
| 132 |
+
CRITICAL DECISION PROCESS (YOU MUST FOLLOW THIS INTERNALLY):
|
| 133 |
+
|
| 134 |
+
Step 1: Understand the target
|
| 135 |
+
- What gates are required? (e.g., CNOT, RX, RZ)
|
| 136 |
+
- Are parameters needed? (angles like π/3, π/4)
|
| 137 |
+
|
| 138 |
+
Step 2: Analyze current circuit
|
| 139 |
+
- What is already correct?
|
| 140 |
+
- What is missing?
|
| 141 |
+
- What is wrong or unnecessary?
|
| 142 |
+
|
| 143 |
+
Step 3: Evaluate improvement
|
| 144 |
+
- Which action will MOST increase fidelity?
|
| 145 |
+
- Will adding this gate help or hurt under noise?
|
| 146 |
+
- Is circuit becoming too deep?
|
| 147 |
+
|
| 148 |
+
Step 4: Choose action strategically
|
| 149 |
+
- Prefer actions that move toward target structure
|
| 150 |
+
- Avoid random or repeated gates
|
| 151 |
+
- Use parametric gates (RX, RZ) when precise tuning is required
|
| 152 |
+
|
| 153 |
+
---
|
| 154 |
+
|
| 155 |
+
STRICT RULES:
|
| 156 |
|
| 157 |
+
- DO NOT repeat the same useless pattern (e.g., H → CNOT blindly).
|
| 158 |
+
- DO NOT use STOP unless:
|
| 159 |
+
- Fidelity is already high (>0.95), OR
|
| 160 |
+
- No further improvement is possible.
|
| 161 |
+
- For unitary/parametric tasks:
|
| 162 |
+
- You MUST use RX/RZ gates with meaningful parameters.
|
| 163 |
+
- Avoid using H unless clearly useful.
|
| 164 |
+
- Prefer minimal circuits (depth matters due to noise).
|
| 165 |
+
- If a step reduces fidelity, consider REMOVE.
|
| 166 |
+
|
| 167 |
+
---
|
| 168 |
+
|
| 169 |
+
ANTI-PATTERN WARNING (VERY IMPORTANT):
|
| 170 |
+
|
| 171 |
+
If you find yourself repeating:
|
| 172 |
+
H → CNOT → STOP
|
| 173 |
+
|
| 174 |
+
You are WRONG.
|
| 175 |
+
|
| 176 |
+
Re-evaluate the task and choose a better action.
|
| 177 |
+
|
| 178 |
+
---
|
| 179 |
+
|
| 180 |
+
OUTPUT FORMAT:
|
| 181 |
+
|
| 182 |
+
Return ONLY the best action as JSON:
|
| 183 |
+
{
|
| 184 |
+
"action_type": "...",
|
| 185 |
+
"gate": "...",
|
| 186 |
+
"qubits": [...],
|
| 187 |
+
"parameter": ...
|
| 188 |
+
}
|
| 189 |
+
""")
|
| 190 |
|
| 191 |
# ---------------------------------------------------------------------------
|
| 192 |
# LLM interaction
|
| 193 |
# ---------------------------------------------------------------------------
|
| 194 |
|
| 195 |
def build_user_prompt(obs_data: Dict[str, Any], step: int, history: List[str]) -> str:
|
| 196 |
+
"""Optimized decision-making prompt (low tokens + high control)."""
|
| 197 |
+
|
| 198 |
+
# 🔹 Compact circuit (token-efficient)
|
| 199 |
+
circuit = [f"{g['gate']}({','.join(map(str, g['qubits']))})"
|
| 200 |
+
for g in obs_data.get("circuit_gates", [])]
|
| 201 |
+
|
| 202 |
+
# 🔹 Short history (avoid token waste)
|
| 203 |
+
history_block = "\n".join(history[-2:]) if history else "None"
|
| 204 |
+
|
| 205 |
+
return textwrap.dedent(f"""
|
| 206 |
+
TASK:
|
| 207 |
+
{obs_data.get('target_description', 'unknown')}
|
| 208 |
+
|
| 209 |
+
STATE:
|
| 210 |
+
Fidelity={obs_data.get('fidelity', 0.0):.3f}, Score={obs_data.get('score', 0.0):.3f}
|
| 211 |
+
Depth={obs_data.get('depth', 0)}, Steps_left={obs_data.get('max_steps', 20) - obs_data.get('steps_taken', 0)}
|
| 212 |
+
|
| 213 |
+
CIRCUIT:
|
| 214 |
+
{circuit if circuit else "empty"}
|
| 215 |
+
|
| 216 |
+
RECENT:
|
| 217 |
+
{history_block}
|
| 218 |
+
|
| 219 |
+
THINK:
|
| 220 |
+
1. What is the TARGET structure? (e.g., CNOT, RY, RZ)
|
| 221 |
+
2. What is MISSING from current circuit?
|
| 222 |
+
3. Will next step INCREASE fidelity?
|
| 223 |
+
|
| 224 |
+
RULES:
|
| 225 |
+
- Do NOT repeat useless gates
|
| 226 |
+
- Do NOT use STOP unless fidelity > 0.9
|
| 227 |
+
- Use RY/RZ for parametric/unitary tasks
|
| 228 |
+
- Prefer minimal depth (noise penalty)
|
| 229 |
+
|
| 230 |
+
OUTPUT:
|
| 231 |
+
Return ONLY one JSON action.
|
| 232 |
""")
|
| 233 |
|
| 234 |
|
|
|
|
| 368 |
|
| 369 |
# Final score = aggregate score from the environment
|
| 370 |
score = obs_data.get("score", 0.0)
|
| 371 |
+
score = min(max(score, 0.0001), 0.9999)
|
| 372 |
success = obs_data.get("fidelity", 0.0) >= SUCCESS_FIDELITY
|
| 373 |
|
| 374 |
finally:
|
server/my_env_environment.py
CHANGED
|
@@ -669,7 +669,7 @@ class QuantumCircuitEnvironment(Environment):
|
|
| 669 |
aggregate *= max(0.3, 1.0 - penalty)
|
| 670 |
|
| 671 |
# Final clamp
|
| 672 |
-
aggregate = max(0.
|
| 673 |
assert 0.0 <= aggregate <= 1.0, f"Aggregate score out of range: {aggregate}"
|
| 674 |
|
| 675 |
return {
|
|
|
|
| 669 |
aggregate *= max(0.3, 1.0 - penalty)
|
| 670 |
|
| 671 |
# Final clamp
|
| 672 |
+
aggregate = max(0.0001, min(0.9999, aggregate))
|
| 673 |
assert 0.0 <= aggregate <= 1.0, f"Aggregate score out of range: {aggregate}"
|
| 674 |
|
| 675 |
return {
|