Spaces:
Running on Zero
Running on Zero
Private CPU-first synthetic compute tests with temporary-file cleanup
Browse files- app.py +19 -35
- cloud_probe.py +63 -0
app.py
CHANGED
|
@@ -1,43 +1,27 @@
|
|
| 1 |
-
import spaces
|
| 2 |
import gradio as gr
|
| 3 |
-
from
|
| 4 |
-
from training_smoke import validate_uploads, execute_smoke
|
| 5 |
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
@spaces.GPU(duration=45)
|
| 10 |
-
def probe():
|
| 11 |
-
return qualify()
|
| 12 |
|
| 13 |
@spaces.GPU(duration=90)
|
| 14 |
-
def
|
| 15 |
-
return
|
| 16 |
-
|
| 17 |
-
def smoke(track, network):
|
| 18 |
-
# Reject unsupported inputs on CPU before requesting a GPU lease.
|
| 19 |
-
return leased_smoke(validate_uploads(track, network))
|
| 20 |
|
| 21 |
with gr.Blocks() as demo:
|
| 22 |
-
gr.Markdown(
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
network = gr.File(label="Formula network", file_types=[".evolution"], type="filepath")
|
| 35 |
-
run = gr.Button("Run bounded training test")
|
| 36 |
-
report = gr.JSON(label="Training receipt")
|
| 37 |
-
candidate = gr.File(label="Candidate network")
|
| 38 |
-
receipt = gr.File(label="Download receipt")
|
| 39 |
-
run.click(smoke, inputs=[track, network], outputs=[report, candidate, receipt],
|
| 40 |
-
api_name="smoke", concurrency_limit=1)
|
| 41 |
|
| 42 |
-
if __name__
|
| 43 |
demo.queue(max_size=1).launch()
|
|
|
|
| 1 |
+
import spaces
|
| 2 |
import gradio as gr
|
| 3 |
+
from cloud_probe import run_probe
|
|
|
|
| 4 |
|
| 5 |
+
def cpu_smoke():
|
| 6 |
+
return run_probe(False)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
|
| 8 |
@spaces.GPU(duration=90)
|
| 9 |
+
def gpu_smoke():
|
| 10 |
+
return run_probe(True)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
with gr.Blocks() as demo:
|
| 13 |
+
gr.Markdown('''# AI Learns To Drive — private compute test
|
| 14 |
+
Simulator by [Zorro909](https://github.com/Zorro909/driving_sim_rs).
|
| 15 |
+
UI and HF implementation by TiGa (seeker-cyber-maker).
|
| 16 |
+
|
| 17 |
+
Fixed synthetic network, 4 cars, 1 generation, 60 ticks. CPU runs without a GPU lease.
|
| 18 |
+
GPU uses up to 90 seconds of included allowance; check quota first. No automatic runs.
|
| 19 |
+
No user uploads; temporary model files are deleted before the receipt is returned.
|
| 20 |
+
This tests backend execution, not useful learning, performance, or full UI integration.
|
| 21 |
+
''')
|
| 22 |
+
report=gr.JSON(label='Execution receipt')
|
| 23 |
+
gr.Button('Run CPU-only test').click(cpu_smoke,outputs=report,api_name='cpu_smoke',concurrency_limit=1,concurrency_id='native')
|
| 24 |
+
gr.Button('Run GPU test').click(gpu_smoke,outputs=report,api_name='gpu_smoke',concurrency_limit=1,concurrency_id='native')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
|
| 26 |
+
if __name__=='__main__':
|
| 27 |
demo.queue(max_size=1).launch()
|
cloud_probe.py
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Fixed synthetic CPU/CUDA smoke test; no uploads or retained model artifacts."""
|
| 2 |
+
import gzip
|
| 3 |
+
import hashlib
|
| 4 |
+
import json
|
| 5 |
+
import os
|
| 6 |
+
from pathlib import Path
|
| 7 |
+
import subprocess
|
| 8 |
+
import tempfile
|
| 9 |
+
import time
|
| 10 |
+
|
| 11 |
+
ROOT = Path(__file__).resolve().parent
|
| 12 |
+
|
| 13 |
+
def run_probe(gpu=False):
|
| 14 |
+
from probe_core import verify_artifacts, qualify
|
| 15 |
+
verify_artifacts()
|
| 16 |
+
qualification = qualify() if gpu else None
|
| 17 |
+
if gpu and not qualification['qualified_for_next_test']:
|
| 18 |
+
return {'status':'qualification_failed','qualification':qualification}
|
| 19 |
+
binary=ROOT/'bin/altd-sim'
|
| 20 |
+
binary.chmod(0o755)
|
| 21 |
+
network={'shape':[1,2],'weights':[[[0.0,0.0]]],'biases':[[0.0,1.0]],
|
| 22 |
+
'inputs':['speed'],'outputs':['Steering','Acceleration']}
|
| 23 |
+
model={'sensor_layout':{'names':['speed'],'sensors':[{'$type':'speed'}]}}
|
| 24 |
+
settings={'population':4,'selection_algorithm':'best','selection_size':1,
|
| 25 |
+
'crossover':'none','mutation_rate':0.01,'adaptive_mutation':False,'weight_decay':0,
|
| 26 |
+
'preserve_parents':'on_custom','preserve_parents_size':1,
|
| 27 |
+
'rewards':[{'metric':'total_score','type':'default','weight':1}]}
|
| 28 |
+
report={'backend_requested':'cuda' if gpu else 'cpu','population':4,'generations':1,
|
| 29 |
+
'ticks':60,'seed':42,'qualification':qualification,'speedup_verified':False}
|
| 30 |
+
with tempfile.TemporaryDirectory(prefix='tiga-probe-') as directory:
|
| 31 |
+
work=Path(directory)
|
| 32 |
+
for name,value in [('network',network),('model',model),('settings',settings)]:
|
| 33 |
+
(work/(name+'.json')).write_text(json.dumps(value))
|
| 34 |
+
command=[str(binary),'--math-profile','proton','--threads','1','train-scratch']
|
| 35 |
+
if gpu: command+=['--gpu']
|
| 36 |
+
command+=['--scene',str(ROOT/'tracks/A01 Beginner.scene.json'),
|
| 37 |
+
'--spawn-trace',str(ROOT/'tracks/A01 Beginner.spawn.json'),
|
| 38 |
+
'--network',str(work/'network.json'),'--init-network',str(work/'network.json'),
|
| 39 |
+
'--model',str(work/'model.json'),'--settings',str(work/'settings.json'),
|
| 40 |
+
'--shape','1,2','--population','4','--generations','1','--ticks','60',
|
| 41 |
+
'--seed','42','--batch-count','2','--out-dir',str(work/'out'),
|
| 42 |
+
'--mutation-start','.01','--mutation-end','.01','--schedule','linear','--save-final-candidate']
|
| 43 |
+
# Preserve only native-loader/device plumbing, never provider credentials.
|
| 44 |
+
keys=('PATH','LD_LIBRARY_PATH','LD_PRELOAD','CUDA_VISIBLE_DEVICES','NVIDIA_VISIBLE_DEVICES')
|
| 45 |
+
env={k:os.environ[k] for k in keys if k in os.environ}
|
| 46 |
+
env.update(HOME=directory,TMPDIR=directory,ALTD_GPU_LIB=str(ROOT/'bin/libaltd_gpu.so'))
|
| 47 |
+
started=time.perf_counter()
|
| 48 |
+
try:
|
| 49 |
+
result=subprocess.run(command,cwd=work,env=env,capture_output=True,text=True,timeout=30)
|
| 50 |
+
report.update(returncode=result.returncode,wall_seconds=time.perf_counter()-started,
|
| 51 |
+
stderr=result.stderr[-4000:],stdout=result.stdout[-4000:])
|
| 52 |
+
candidate=work/'out/candidate.json'
|
| 53 |
+
report['status']='failed'
|
| 54 |
+
if result.returncode==0 and candidate.is_file():
|
| 55 |
+
value=json.loads(candidate.read_text())
|
| 56 |
+
report.update(status='candidate_created',shape=value['shape'],
|
| 57 |
+
candidate_sha256=hashlib.sha256(candidate.read_bytes()).hexdigest(),
|
| 58 |
+
history=[json.loads(line) for line in (work/'out/log.jsonl').read_text().splitlines()])
|
| 59 |
+
except subprocess.TimeoutExpired:
|
| 60 |
+
report.update(status='timeout',wall_seconds=time.perf_counter()-started)
|
| 61 |
+
report['temporary_directory_removed']=not work.exists()
|
| 62 |
+
report['candidate_retained']=False
|
| 63 |
+
return report
|