QEMU/KVM VMs
Run CPU-compatible Ubuntu and Windows tasks as complete QEMU/KVM guest machines on a local Linux host. ALE creates one disposable VM per run unit.
configs/environments/qemu.yaml with
selected_tasks/cpu_unlicensed.txt. GPU passthrough and licensed
tasks are outside the current provider scope.
Architecture and naming
The task sandbox is the guest VM, not the outer Docker container. Docker
packages the ALE QEMU runner and supervises its networking, noVNC, and
process lifecycle. The runner is derived from the
CUA and
Dockur QEMU stack. The
user-facing name is therefore QEMU/KVM VMs, while the
stable configuration identifier is provider: qemu. A future
VMware implementation would be documented as a separate sibling provider.
Host requirements
- A Linux host.
- Docker available to the current user.
- Hardware or nested virtualization exposed as readable and writable
/dev/kvm. - Enough memory for every concurrently active guest.
- Enough disk for the cached base images and growing per-run overlays. Plan for about 350 GB when caching both published disks.
docker info
test -r /dev/kvm && test -w /dev/kvm
df -h ~/.cache
If ALE itself runs inside a cloud VM, that host must expose nested
virtualization. The provider fails before provisioning when Docker or
/dev/kvm is unavailable.
Understand the two downloads
-
Runner image. Docker pulls
agentslastexam/ale-qemu:0.2.0from Docker Hub when it is missing. It contains QEMU and runner infrastructure, not a guest OS. - Guest disk. The host provider downloads the selected Ubuntu or Windows qcow2 from the ALE qcow2 dataset and reconstructs multipart disks when necessary.
Base disks are cached under ~/.cache/ale/qemu/images. Each
run creates a small qcow2 overlay under
~/.cache/ale/qemu/runtime/slots. The overlay grows only as the
guest writes changed blocks and is removed with cleanup_mode:
delete.
Disk sources
The shipped profile uses logical Hugging Face paths. A snapshot can instead use a GCS object or an existing host file:
qemu:
disk_source: hf://agents-last-exam/ale-images-qcow2/ale-win10.qcow2
# or: gs://ale-data-public/images/ale-win10.qcow2
# or: /absolute/path/to/ale-win10.qcow2
root: ~/.cache/ale/qemu
runner_image: agentslastexam/ale-qemu:0.2.0
runner_pull_policy: missing
GCS disk downloads require gcloud or gsutil on
the host. The provider records source metadata and refreshes a cached disk
when the remote object generation changes.
Run the demo tasks
Create an experiment in the repository root:
name: local_vm_demo
secret_file: secret/.env
agents:
- configs/agents/claude_code.yaml
environment: configs/environments/qemu.yaml
tasks: selected_tasks/hello_both.txt
output:
root: .logs/ale
concurrency: 1
wall_time_s: 1800
cleanup_mode: delete
uv run python -m ale_run run local_vm_demo.yaml --dry-run
uv run python -m ale_run run local_vm_demo.yaml
demo/hello boots Ubuntu and demo/hello_win boots
Windows. Both produce and grade an output file, exercising provisioning,
agent execution, output collection, evaluation, and cleanup.
Task coverage
cpu_unlicensed.txt currently contains 140 unlicensed tasks:
all 105 cpu-free-ubuntu tasks and 35 cpu-free
Windows tasks. Tasks that require GPU execution, licensed software, or a
missing application are excluded.
Resource sizing and concurrency
Each guest normally derives its vCPU and memory shape from the task card's
GCE machineType. The schema also accepts explicit
vm.vcpus and vm.memory_gb values.
Per-snapshot qemu.vcpus and qemu.memory_gb can
override either source.
ALE does not reserve host resources globally. Start with low concurrency, then monitor available memory, disk latency, and overlay growth. A vCPU allocation is a guest limit, not guaranteed constant utilization, but guest memory allocations still determine the host's worst-case pressure.
Output options
With output_path: local, each guest copies its output through
a per-run Samba share into the host run directory. CUA remains a fallback,
not the normal bulk-transfer path.
With a gs:// output path, configure
gcs_sa_key. ALE injects the key into the guest and the guest
uploads directly with gsutil. See
Choose where task output goes.
Current limits
- GPU passthrough is not implemented.
task_data_source: local:...is not implemented for QEMU guests. Published task data must be baked into the qcow2, or staged through another supported guest-side source.- macOS and Windows hosts are not supported.
- There is no host-wide CPU, memory, or disk admission controller.
docs/local-qemu.md.