itsalissonsilva commited on
Commit
6fbf1f1
·
verified ·
1 Parent(s): 64f2e15

Score fresh quantum circuit and larger/nonlocal holdouts using independently frozen isolated executor

Browse files
v2_execution/execution.json ADDED
The diff for this file is too large to render. See raw diff
 
v2_execution/quantum_sandbox_v2.py ADDED
@@ -0,0 +1,317 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """V2 restricted quantum executor; v1 remains frozen in quantum_sandbox.py.
2
+
3
+ AST screening is combined with nobody UID, cleared environment, process/resource
4
+ limits and seccomp denial of filesystem opens, networking and process execution.
5
+ Libraries are imported/warmed in the parent before any untrusted code runs.
6
+ """
7
+
8
+ import ast
9
+ import contextlib
10
+ import ctypes
11
+ import ctypes.util
12
+ import errno
13
+ import importlib
14
+ import io
15
+ import multiprocessing as mp
16
+ import os
17
+ import resource
18
+
19
+ for variable in ["OPENBLAS_NUM_THREADS", "OMP_NUM_THREADS", "MKL_NUM_THREADS"]:
20
+ os.environ[variable] = "1"
21
+
22
+ import numpy as np
23
+
24
+ MODULES = {
25
+ "numpy",
26
+ "numpy.linalg",
27
+ "math",
28
+ "cmath",
29
+ "qiskit",
30
+ "qiskit.quantum_info",
31
+ "pennylane",
32
+ "cirq",
33
+ }
34
+ ATTRIBUTES = set(
35
+ "array asarray zeros ones eye pi sqrt exp sin cos conj conjugate transpose reshape flatten ravel squeeze astype complex64 complex128 float32 float64 norm kron real imag T shape size data QuantumCircuit Statevector from_instruction h x y z ry rx rz cx cz swap s sdg t tdg sx barrier append device qnode state RY RX RZ Rot PhaseShift Identity PauliX PauliY PauliZ Hadamard CNOT CZ SWAP LineQubit range Circuit Simulator simulate final_state_vector H X Y Z CXPowGate ZPowGate XPowGate HPowGate controlled on inverse quantum_info".split()
36
+ )
37
+ # Documented Cirq gate aliases, independent of any v2 model outputs. They were
38
+ # absent from v1's conservative supported API. No isolation rule is relaxed.
39
+ ATTRIBUTES.update({"CX", "Rx", "Ry", "Rz"})
40
+ BUILTINS = {
41
+ "range": lambda *a: bounded_range(*a),
42
+ "enumerate": enumerate,
43
+ "zip": zip,
44
+ "len": len,
45
+ "list": list,
46
+ "tuple": tuple,
47
+ "float": float,
48
+ "int": int,
49
+ "complex": complex,
50
+ "print": print,
51
+ "abs": abs,
52
+ "sum": sum,
53
+ "min": min,
54
+ "max": max,
55
+ "reversed": reversed,
56
+ }
57
+ FORBIDDEN = (
58
+ ast.ClassDef,
59
+ ast.AsyncFunctionDef,
60
+ ast.Await,
61
+ ast.While,
62
+ ast.Try,
63
+ ast.With,
64
+ ast.AsyncWith,
65
+ ast.Raise,
66
+ ast.Delete,
67
+ ast.Global,
68
+ ast.Nonlocal,
69
+ ast.Lambda,
70
+ ast.Yield,
71
+ ast.YieldFrom,
72
+ ast.Match,
73
+ )
74
+ LIB = None
75
+
76
+
77
+ def bounded_range(*args):
78
+ value = range(*args)
79
+ if len(value) > 1024:
80
+ raise ValueError("range limit")
81
+ return value
82
+
83
+
84
+ def screen(program):
85
+ if len(program) > 25000:
86
+ raise ValueError("program length limit")
87
+ tree = ast.parse(program)
88
+ if sum(1 for _ in ast.walk(tree)) > 6000:
89
+ raise ValueError("AST node limit")
90
+ for node in ast.walk(tree):
91
+ if isinstance(node, FORBIDDEN):
92
+ raise ValueError("unsupported syntax: " + type(node).__name__)
93
+ if isinstance(node, ast.Name) and (
94
+ node.id.startswith("_")
95
+ or node.id
96
+ in {
97
+ "eval",
98
+ "exec",
99
+ "compile",
100
+ "open",
101
+ "getattr",
102
+ "setattr",
103
+ "globals",
104
+ "locals",
105
+ "vars",
106
+ "type",
107
+ "object",
108
+ "input",
109
+ "help",
110
+ "breakpoint",
111
+ }
112
+ ):
113
+ raise ValueError("forbidden name")
114
+ if isinstance(node, ast.Attribute) and node.attr not in ATTRIBUTES:
115
+ raise ValueError("unsupported attribute: " + node.attr)
116
+ if isinstance(node, ast.Import):
117
+ if any(a.name not in MODULES or (a.asname or "").startswith("_") for a in node.names):
118
+ raise ValueError("unsupported import")
119
+ if isinstance(node, ast.ImportFrom):
120
+ if (
121
+ node.level
122
+ or node.module not in MODULES
123
+ or any(
124
+ a.name not in ATTRIBUTES or (a.asname or "").startswith("_") for a in node.names
125
+ )
126
+ ):
127
+ raise ValueError("unsupported from import")
128
+ if isinstance(node, ast.FunctionDef) and node.name.startswith("_"):
129
+ raise ValueError("forbidden function name")
130
+ return tree
131
+
132
+
133
+ def initialize():
134
+ global LIB
135
+ assert os.name == "posix" and os.getuid() == 0, "Linux root parent required for UID isolation"
136
+ # Resolve/load seccomp before restricting filesystem access.
137
+ library = ctypes.util.find_library("seccomp")
138
+ assert library, "libseccomp is required; never fall back to AST-only execution"
139
+ LIB = ctypes.CDLL(library, use_errno=True)
140
+ LIB.seccomp_init.argtypes = [ctypes.c_uint32]
141
+ LIB.seccomp_init.restype = ctypes.c_void_p
142
+ LIB.seccomp_syscall_resolve_name.argtypes = [ctypes.c_char_p]
143
+ LIB.seccomp_syscall_resolve_name.restype = ctypes.c_int
144
+ LIB.seccomp_rule_add.argtypes = [ctypes.c_void_p, ctypes.c_uint32, ctypes.c_int, ctypes.c_uint]
145
+ LIB.seccomp_load.argtypes = [ctypes.c_void_p]
146
+ LIB.seccomp_release.argtypes = [ctypes.c_void_p]
147
+ from qiskit import QuantumCircuit
148
+ from qiskit.quantum_info import Statevector
149
+ import pennylane as qml
150
+ import cirq
151
+
152
+ qc = QuantumCircuit(2)
153
+ qc.h(0)
154
+ qc.ry(0.3, 1)
155
+ qc.rz(0.17, 0)
156
+ qc.x(0)
157
+ qc.z(1)
158
+ qc.cx(0, 1)
159
+ Statevector.from_instruction(qc)
160
+ device = qml.device("default.qubit", wires=[1, 0])
161
+
162
+ @qml.qnode(device)
163
+ def warm():
164
+ qml.Hadamard(0)
165
+ qml.RY(0.3, wires=1)
166
+ qml.RZ(0.17, wires=0)
167
+ qml.PauliX(0)
168
+ qml.PauliZ(1)
169
+ qml.CNOT(wires=[0, 1])
170
+ return qml.state()
171
+
172
+ warm()
173
+ qubits = cirq.LineQubit.range(2)
174
+ cirq.Simulator(dtype=np.complex128).simulate(
175
+ cirq.Circuit(
176
+ cirq.H(qubits[0]),
177
+ cirq.ry(0.3)(qubits[1]),
178
+ cirq.rz(0.17)(qubits[0]),
179
+ cirq.X(qubits[0]),
180
+ cirq.Z(qubits[1]),
181
+ cirq.CNOT(*qubits),
182
+ ),
183
+ qubit_order=list(reversed(qubits)),
184
+ )
185
+ # Warm Python import machinery and serialization before fork/lockdown.
186
+ for module in MODULES:
187
+ importlib.import_module(module)
188
+ importlib.import_module("socket")
189
+ return dict(
190
+ qiskit=importlib.import_module("qiskit").__version__,
191
+ pennylane=qml.__version__,
192
+ cirq=cirq.__version__,
193
+ )
194
+
195
+
196
+ def lockdown():
197
+ os.environ.clear()
198
+ os.setgroups([])
199
+ os.setgid(65534)
200
+ os.setuid(65534)
201
+ resource.setrlimit(resource.RLIMIT_CPU, (15, 15))
202
+ # Native numeric runtimes reserve large virtual address spaces. Physical
203
+ # memory remains bounded by the HF CPU job container's memory allocation.
204
+ resource.setrlimit(resource.RLIMIT_AS, (16 * 1024**3, 16 * 1024**3))
205
+ resource.setrlimit(resource.RLIMIT_FSIZE, (0, 0))
206
+ resource.setrlimit(resource.RLIMIT_CORE, (0, 0))
207
+ resource.setrlimit(resource.RLIMIT_NPROC, (32, 32))
208
+ libc = ctypes.CDLL(None, use_errno=True)
209
+ assert libc.prctl(38, 1, 0, 0, 0) == 0, "PR_SET_NO_NEW_PRIVS failed"
210
+ policy = LIB.seccomp_init(0x7FFF0000) # SCMP_ACT_ALLOW
211
+ assert policy
212
+ deny = 0x00050000 | errno.EPERM # SCMP_ACT_ERRNO(EPERM)
213
+ for name in [
214
+ "open",
215
+ "openat",
216
+ "openat2",
217
+ "creat",
218
+ "socket",
219
+ "socketpair",
220
+ "connect",
221
+ "accept",
222
+ "accept4",
223
+ "bind",
224
+ "listen",
225
+ "sendto",
226
+ "sendmsg",
227
+ "execve",
228
+ "execveat",
229
+ "ptrace",
230
+ "process_vm_readv",
231
+ "process_vm_writev",
232
+ "mount",
233
+ "umount2",
234
+ "bpf",
235
+ "userfaultfd",
236
+ ]:
237
+ syscall = LIB.seccomp_syscall_resolve_name(name.encode())
238
+ if syscall >= 0:
239
+ assert LIB.seccomp_rule_add(policy, deny, syscall, 0) == 0, name
240
+ assert LIB.seccomp_load(policy) == 0, "seccomp load failed"
241
+ LIB.seccomp_release(policy)
242
+
243
+
244
+ def safe_import(name, globals=None, locals=None, fromlist=(), level=0):
245
+ if name not in MODULES or level:
246
+ raise ImportError("module not allowed")
247
+ module = importlib.import_module(name)
248
+ return module if fromlist else importlib.import_module(name.split(".")[0])
249
+
250
+
251
+ def worker(program, qubits, connection, mode):
252
+ try:
253
+ lockdown()
254
+ if mode == "isolation_check":
255
+ import socket
256
+
257
+ file_blocked = network_blocked = False
258
+ try:
259
+ open("/etc/hostname").read()
260
+ except PermissionError:
261
+ file_blocked = True
262
+ try:
263
+ socket.socket()
264
+ except PermissionError:
265
+ network_blocked = True
266
+ connection.send(
267
+ dict(
268
+ file_opens_blocked=file_blocked,
269
+ network_blocked=network_blocked,
270
+ uid=os.getuid(),
271
+ environment_empty=not os.environ,
272
+ )
273
+ )
274
+ return
275
+ tree = screen(program)
276
+ safe = dict(BUILTINS, __import__=safe_import)
277
+ namespace = {"__builtins__": safe}
278
+ with contextlib.redirect_stdout(io.StringIO()), contextlib.redirect_stderr(io.StringIO()):
279
+ exec(compile(tree, "<restricted-quantum>", "exec"), namespace, namespace)
280
+ value = np.asarray(namespace["state"], dtype=np.complex128).reshape(-1)
281
+ assert value.shape == (2**qubits,) and np.isfinite(value).all()
282
+ connection.send(
283
+ dict(
284
+ status="executed",
285
+ real=value.real.tolist(),
286
+ imag=value.imag.tolist(),
287
+ norm=float(np.linalg.norm(value)),
288
+ )
289
+ )
290
+ except BaseException as error:
291
+ connection.send(
292
+ dict(status="rejected_or_error", error=type(error).__name__, detail=str(error)[:300])
293
+ )
294
+ finally:
295
+ connection.close()
296
+
297
+
298
+ def run(program, qubits, mode="program"):
299
+ assert 1 <= qubits <= 8
300
+ ctx = mp.get_context("fork")
301
+ receive, send = ctx.Pipe(duplex=False)
302
+ process = ctx.Process(target=worker, args=(program, qubits, send, mode))
303
+ process.start()
304
+ send.close()
305
+ if receive.poll(20):
306
+ try:
307
+ result = receive.recv()
308
+ except EOFError:
309
+ result = dict(status="worker_exit", exitcode=process.exitcode)
310
+ else:
311
+ result = dict(status="timeout")
312
+ process.join(1)
313
+ if process.is_alive():
314
+ process.kill()
315
+ process.join(2)
316
+ receive.close()
317
+ return result
v2_execution/train_quantum_v2_execute_pilot.py ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Score fresh quantum generations with the independently frozen v2 executor."""
2
+
3
+ import ast
4
+ import hashlib
5
+ import json
6
+ import re
7
+ from collections import defaultdict
8
+ from pathlib import Path
9
+
10
+ import numpy as np
11
+ from huggingface_hub import HfApi, hf_hub_download
12
+ import quantum_sandbox_v2 as sandbox
13
+
14
+ REPO = "itsalissonsilva/QuantumCoder-9B"
15
+
16
+
17
+ def main():
18
+ api = HfApi()
19
+ revision = api.model_info(REPO).sha
20
+ assert api.model_info(REPO).private
21
+
22
+ def get(path, rev=revision):
23
+ return Path(hf_hub_download(REPO, path, revision=rev))
24
+
25
+ preflight = json.loads(get("v2_executor_preflight/preflight.json").read_text())
26
+ source_hash = hashlib.sha256(Path(sandbox.__file__).read_bytes()).hexdigest()
27
+ assert preflight["all_passed"] and len(preflight["reference_checks"]) == 1368
28
+ assert source_hash == preflight["executor_sha256"]
29
+ assert source_hash == hashlib.sha256(get("v2_executor_preflight/quantum_sandbox_v2.py").read_bytes()).hexdigest()
30
+ # No model output is opened until reference and immutable-executor checks pass.
31
+ generations = json.loads(get("curriculum_v2_run/generation_report.json").read_text())
32
+ assert set(generations["conditions"]) == {"base", "adapted"}, "Training/generation incomplete"
33
+ data_file = get("curriculum_v2/rows.json", generations["data_revision"])
34
+ assert hashlib.sha256(data_file.read_bytes()).hexdigest() == preflight["manifest"]["rows_sha256"]
35
+ data = {r["id"]: r for r in json.loads(data_file.read_text()) if r["split"] != "train"}
36
+ assert len(data) == 720
37
+ expected = set(data)
38
+ versions = sandbox.initialize()
39
+ isolation = sandbox.run("", 1, mode="isolation_check")
40
+ assert isolation == preflight["isolation"] and versions == preflight["versions"]
41
+ records = []
42
+ for condition in ["base", "adapted"]:
43
+ outputs = generations["conditions"][condition]
44
+ assert len(outputs) == len(expected) and {r["id"] for r in outputs} == expected
45
+ for output in outputs:
46
+ row = data[output["id"]]
47
+ assert all(row[k] == output[k] for k in ["group_id", "split", "framework", "qubits"])
48
+ program = output["program"]
49
+ wrapped = re.fullmatch(r"\s*```(?:python)?\s*\n(.*?)\n```\s*", program, flags=re.S)
50
+ clean = wrapped.group(1) if wrapped else program
51
+ syntax = True
52
+ imports = set()
53
+ try:
54
+ tree = ast.parse(clean)
55
+ for node in ast.walk(tree):
56
+ if isinstance(node, ast.Import):
57
+ imports.update(a.name.split(".")[0] for a in node.names)
58
+ elif isinstance(node, ast.ImportFrom):
59
+ imports.add((node.module or "").split(".")[0])
60
+ except SyntaxError:
61
+ syntax = False
62
+ outcome = sandbox.run(clean, row["qubits"])
63
+ fidelity = None
64
+ correct = False
65
+ if outcome.get("status") == "executed":
66
+ actual = np.array(outcome["real"])+1j*np.array(outcome["imag"])
67
+ target = np.array(row["state_real"])+1j*np.array(row["state_imag"])
68
+ fidelity = float(abs(np.vdot(target, actual))**2)
69
+ correct = abs(outcome["norm"]-1)<1e-6 and fidelity>1-1e-6
70
+ requested = row["framework"] in imports
71
+ records.append(dict(condition=condition, id=row["id"], group_id=row["group_id"], split=row["split"], framework=row["framework"],
72
+ passed=bool(correct and requested), state_pass=bool(correct), fidelity=fidelity,
73
+ syntax_parses=syntax, requested_framework_import=requested,
74
+ single_fence_unwrapped=wrapped is not None, generated_tokens=output["generated_tokens"],
75
+ at_token_cap=output["at_token_cap"], eos_observed=output["eos_observed"],
76
+ execution={k:v for k,v in outcome.items() if k not in ["real","imag"]},
77
+ program_sha256=hashlib.sha256(program.encode()).hexdigest()))
78
+ if len(records)%100==0:
79
+ print(json.dumps(dict(stage="scoring", n=len(records), condition=condition)), flush=True)
80
+ summary = {}
81
+ for condition in ["base", "adapted"]:
82
+ summary[condition] = {}
83
+ for split in ["validation", "test_iid", "test_stress"]:
84
+ for framework in ["all", "qiskit", "pennylane", "cirq"]:
85
+ chosen = [r for r in records if r["condition"]==condition and r["split"]==split and (framework=="all" or r["framework"]==framework)]
86
+ summary[condition][split+"/"+framework] = dict(n=len(chosen), passed=sum(r["passed"] for r in chosen),
87
+ pass_at_1=float(np.mean([r["passed"] for r in chosen])), state_correct=sum(r["state_pass"] for r in chosen),
88
+ executed=sum(r["execution"].get("status")=="executed" for r in chosen), syntax_valid=sum(r["syntax_parses"] for r in chosen),
89
+ token_cap=sum(r["at_token_cap"] for r in chosen))
90
+ paired = {}
91
+ for split in ["test_iid", "test_stress"]:
92
+ base = {r["id"]:r for r in records if r["condition"]=="base" and r["split"]==split}
93
+ adapted = {r["id"]:r for r in records if r["condition"]=="adapted" and r["split"]==split}
94
+ grouped = defaultdict(list)
95
+ for identifier in sorted(base):
96
+ grouped[base[identifier]["group_id"]].append(int(adapted[identifier]["passed"])-int(base[identifier]["passed"]))
97
+ delta = np.array(list(grouped.values()))
98
+ assert delta.shape == (96,3)
99
+ rng = np.random.default_rng(20261101)
100
+ boot = delta[rng.integers(0,len(delta),size=(5000,len(delta)))].mean(axis=(1,2))
101
+ paired[split] = dict(groups=len(delta), improved=int((delta==1).sum()), regressed=int((delta==-1).sum()),
102
+ pass_delta=float(delta.mean()), group_bootstrap_95=np.quantile(boot,[.025,.975]).tolist())
103
+ report = dict(source_revision=revision, data_revision=generations["data_revision"], executor_sha256=source_hash,
104
+ versions=versions,isolation=isolation,summary=summary,paired=paired,records=records,
105
+ deterministic_renderer_reference_pass_at_1=1.0,
106
+ release_gate_pass=all(p["group_bootstrap_95"][0]>0 for p in paired.values()),
107
+ limitations="One seed, synthetic structured circuit-to-program translation. A deterministic renderer already solves this task perfectly. State fidelity from zero input is not full unitary/process equivalence or novel algorithm discovery. Import presence is a framework-compliance proxy, not data-flow proof. Supported-Python executor may reject other valid implementations. No repair/retry/target-informed edits; only one full-output code fence may be removed. Fresh v2 circuit groups are disjoint from the original failed held-out-Cirq study; v2 explicitly trains all frameworks. V1 failure remains separately reported.")
108
+ folder = Path("v2_execution")
109
+ folder.mkdir(exist_ok=True)
110
+ (folder/"execution.json").write_text(json.dumps(report,indent=2))
111
+ (folder/"train_quantum_v2_execute_pilot.py").write_bytes(Path(__file__).read_bytes())
112
+ (folder/"quantum_sandbox_v2.py").write_bytes(Path(sandbox.__file__).read_bytes())
113
+ commit = api.upload_folder(repo_id=REPO, folder_path=str(folder), path_in_repo="v2_execution",
114
+ commit_message="Score fresh quantum circuit and larger/nonlocal holdouts using independently frozen isolated executor")
115
+ print(json.dumps(dict(revision=commit.oid,summary=summary,paired=paired,gate=report["release_gate_pass"])),flush=True)
116
+
117
+
118
+ if __name__ == "__main__":
119
+ main()