fastevolve 0.3.1__tar.gz → 0.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fastevolve-0.3.1 → fastevolve-0.3.3}/PKG-INFO +42 -18
- {fastevolve-0.3.1 → fastevolve-0.3.3}/README.md +41 -17
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/llm_ensemble/__init__.py +2 -2
- fastevolve-0.3.3/fastevolve/llm_ensemble/ollama.py +100 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/pyproject.toml +1 -1
- {fastevolve-0.3.1 → fastevolve-0.3.3}/uv.lock +1 -1
- fastevolve-0.3.1/fastevolve/llm_ensemble/ollama.py +0 -45
- {fastevolve-0.3.1 → fastevolve-0.3.3}/.claude/settings.local.json +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/.gitignore +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/.python-version +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/__init__.py +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/checkpoint.py +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/config.py +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/controller.py +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/evaluator/__init__.py +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/evaluator/config.py +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/evaluator/evaluator.py +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/evaluator/result.py +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/llm_ensemble/anthropic_llm.py +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/llm_ensemble/base.py +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/llm_ensemble/config.py +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/llm_ensemble/ensemble.py +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/llm_ensemble/openai_llm.py +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/program_database/__init__.py +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/program_database/config.py +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/program_database/database.py +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/program_database/embedder.py +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/program_database/program.py +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/prompt_sampler/__init__.py +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/prompt_sampler/config.py +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/prompt_sampler/sampler.py +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/prompt_sampler/template_library.py +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/fastevolve/telemetry.py +0 -0
- {fastevolve-0.3.1 → fastevolve-0.3.3}/main.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastevolve
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: Minimal open-source AlphaEvolve: LLM-driven program evolution with MAP-Elites islands, cascade evaluation, and a local Ollama ensemble.
|
|
5
5
|
Project-URL: Homepage, https://github.com/tiagomonteiro0715/fastevolve
|
|
6
6
|
Project-URL: Repository, https://github.com/tiagomonteiro0715/fastevolve
|
|
@@ -34,20 +34,47 @@ Minimal open-source AlphaEvolve: LLM-driven program evolution with MAP-Elites is
|
|
|
34
34
|
|
|
35
35
|
## Install
|
|
36
36
|
|
|
37
|
+
### 1. Install uv (one-time)
|
|
38
|
+
|
|
39
|
+
uv is a fast Python package manager. Pick the line for your OS:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# macOS / Linux
|
|
43
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
44
|
+
|
|
45
|
+
# Windows (PowerShell)
|
|
46
|
+
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Or via Homebrew (`brew install uv`), pipx (`pipx install uv`), or pip (`pip install uv`).
|
|
50
|
+
|
|
51
|
+
### 2. Add fastevolve to a new project
|
|
52
|
+
|
|
37
53
|
```bash
|
|
38
|
-
uv
|
|
54
|
+
uv init my-evolve-project
|
|
55
|
+
cd my-evolve-project
|
|
56
|
+
uv add fastevolve
|
|
39
57
|
```
|
|
40
58
|
|
|
41
|
-
|
|
59
|
+
OpenAI and Anthropic SDKs are optional extras — install whichever you need:
|
|
42
60
|
|
|
43
61
|
```bash
|
|
44
|
-
uv
|
|
45
|
-
uv
|
|
46
|
-
uv
|
|
62
|
+
uv add "fastevolve[openai]" # adds the OpenAI SDK
|
|
63
|
+
uv add "fastevolve[anthropic]" # adds the Anthropic SDK
|
|
64
|
+
uv add "fastevolve[all]" # both
|
|
47
65
|
```
|
|
48
66
|
|
|
49
67
|
If you only use Ollama, skip the extras — neither SDK will be imported.
|
|
50
68
|
|
|
69
|
+
### 3. Or clone this repo and sync
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
git clone https://github.com/tiagomonteiro0715/fastevolve.git
|
|
73
|
+
cd fastevolve
|
|
74
|
+
uv sync # core
|
|
75
|
+
uv sync --extra all # core + OpenAI + Anthropic
|
|
76
|
+
```
|
|
77
|
+
|
|
51
78
|
## Quick start in code
|
|
52
79
|
|
|
53
80
|
### Local (with Ollama)
|
|
@@ -152,22 +179,19 @@ print(result.best.code)
|
|
|
152
179
|
|
|
153
180
|
### Google Colab (with Ollama)
|
|
154
181
|
|
|
155
|
-
Ollama can run on Colab if you install it, start the daemon in the background, and pull a
|
|
182
|
+
Ollama can run on Colab if you install it, start the daemon in the background, and pull a model. Tested working on the free CPU runtime with a tiny model (`qwen2.5:0.5b`).
|
|
183
|
+
|
|
184
|
+
**On Colab Pro / Pro+**: switch to an A100 or L4 GPU runtime (`Runtime → Change runtime type → A100 GPU`) and swap the model for something bigger — `qwen2.5-coder:7b`, `llama3.1:8b`, or `gemma2:9b` all fit comfortably and produce dramatically better evolution candidates than `0.5b`. Pro+'s longer sessions (24 h) and background execution also mean you can leave a 1000-iteration run going overnight without keeping the tab open.
|
|
156
185
|
|
|
157
186
|
```python
|
|
158
|
-
# 1. Install ollama and fastevolve
|
|
187
|
+
# 1. Install ollama (zstd is required by the install script) and fastevolve via uv
|
|
188
|
+
!apt-get -qq install -y zstd
|
|
159
189
|
!curl -fsSL https://ollama.com/install.sh | sh
|
|
160
|
-
!pip install
|
|
161
|
-
|
|
162
|
-
# 2. Start the ollama daemon in the background
|
|
163
|
-
import subprocess, time
|
|
164
|
-
subprocess.Popen(["ollama", "serve"])
|
|
165
|
-
time.sleep(5) # give it a moment to bind to port 11434
|
|
166
|
-
|
|
167
|
-
# 3. Pull a small model (qwen2.5:0.5b is ~400 MB and fits the free CPU runtime)
|
|
168
|
-
!ollama pull qwen2.5:0.5b
|
|
190
|
+
!pip install uv
|
|
191
|
+
!uv pip install -q fastevolve
|
|
169
192
|
|
|
170
|
-
#
|
|
193
|
+
# 2. Run fastevolve — it starts the ollama daemon automatically with GPU-aware
|
|
194
|
+
# optimizations (flash attention, q8_0 KV cache, parallel decoding) when a GPU is detected.
|
|
171
195
|
from fastevolve import Config, Controller
|
|
172
196
|
from fastevolve.llm_ensemble import ModelConfig
|
|
173
197
|
|
|
@@ -4,20 +4,47 @@ Minimal open-source AlphaEvolve: LLM-driven program evolution with MAP-Elites is
|
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
|
+
### 1. Install uv (one-time)
|
|
8
|
+
|
|
9
|
+
uv is a fast Python package manager. Pick the line for your OS:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# macOS / Linux
|
|
13
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
14
|
+
|
|
15
|
+
# Windows (PowerShell)
|
|
16
|
+
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Or via Homebrew (`brew install uv`), pipx (`pipx install uv`), or pip (`pip install uv`).
|
|
20
|
+
|
|
21
|
+
### 2. Add fastevolve to a new project
|
|
22
|
+
|
|
7
23
|
```bash
|
|
8
|
-
uv
|
|
24
|
+
uv init my-evolve-project
|
|
25
|
+
cd my-evolve-project
|
|
26
|
+
uv add fastevolve
|
|
9
27
|
```
|
|
10
28
|
|
|
11
|
-
|
|
29
|
+
OpenAI and Anthropic SDKs are optional extras — install whichever you need:
|
|
12
30
|
|
|
13
31
|
```bash
|
|
14
|
-
uv
|
|
15
|
-
uv
|
|
16
|
-
uv
|
|
32
|
+
uv add "fastevolve[openai]" # adds the OpenAI SDK
|
|
33
|
+
uv add "fastevolve[anthropic]" # adds the Anthropic SDK
|
|
34
|
+
uv add "fastevolve[all]" # both
|
|
17
35
|
```
|
|
18
36
|
|
|
19
37
|
If you only use Ollama, skip the extras — neither SDK will be imported.
|
|
20
38
|
|
|
39
|
+
### 3. Or clone this repo and sync
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
git clone https://github.com/tiagomonteiro0715/fastevolve.git
|
|
43
|
+
cd fastevolve
|
|
44
|
+
uv sync # core
|
|
45
|
+
uv sync --extra all # core + OpenAI + Anthropic
|
|
46
|
+
```
|
|
47
|
+
|
|
21
48
|
## Quick start in code
|
|
22
49
|
|
|
23
50
|
### Local (with Ollama)
|
|
@@ -122,22 +149,19 @@ print(result.best.code)
|
|
|
122
149
|
|
|
123
150
|
### Google Colab (with Ollama)
|
|
124
151
|
|
|
125
|
-
Ollama can run on Colab if you install it, start the daemon in the background, and pull a
|
|
152
|
+
Ollama can run on Colab if you install it, start the daemon in the background, and pull a model. Tested working on the free CPU runtime with a tiny model (`qwen2.5:0.5b`).
|
|
153
|
+
|
|
154
|
+
**On Colab Pro / Pro+**: switch to an A100 or L4 GPU runtime (`Runtime → Change runtime type → A100 GPU`) and swap the model for something bigger — `qwen2.5-coder:7b`, `llama3.1:8b`, or `gemma2:9b` all fit comfortably and produce dramatically better evolution candidates than `0.5b`. Pro+'s longer sessions (24 h) and background execution also mean you can leave a 1000-iteration run going overnight without keeping the tab open.
|
|
126
155
|
|
|
127
156
|
```python
|
|
128
|
-
# 1. Install ollama and fastevolve
|
|
157
|
+
# 1. Install ollama (zstd is required by the install script) and fastevolve via uv
|
|
158
|
+
!apt-get -qq install -y zstd
|
|
129
159
|
!curl -fsSL https://ollama.com/install.sh | sh
|
|
130
|
-
!pip install
|
|
131
|
-
|
|
132
|
-
# 2. Start the ollama daemon in the background
|
|
133
|
-
import subprocess, time
|
|
134
|
-
subprocess.Popen(["ollama", "serve"])
|
|
135
|
-
time.sleep(5) # give it a moment to bind to port 11434
|
|
136
|
-
|
|
137
|
-
# 3. Pull a small model (qwen2.5:0.5b is ~400 MB and fits the free CPU runtime)
|
|
138
|
-
!ollama pull qwen2.5:0.5b
|
|
160
|
+
!pip install uv
|
|
161
|
+
!uv pip install -q fastevolve
|
|
139
162
|
|
|
140
|
-
#
|
|
163
|
+
# 2. Run fastevolve — it starts the ollama daemon automatically with GPU-aware
|
|
164
|
+
# optimizations (flash attention, q8_0 KV cache, parallel decoding) when a GPU is detected.
|
|
141
165
|
from fastevolve import Config, Controller
|
|
142
166
|
from fastevolve.llm_ensemble import ModelConfig
|
|
143
167
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from .config import ModelConfig, EnsembleConfig
|
|
2
2
|
from .base import BaseLLM
|
|
3
|
-
from .ollama import OllamaLLM
|
|
3
|
+
from .ollama import OllamaLLM, start_ollama
|
|
4
4
|
from .ensemble import LLMEnsemble
|
|
5
5
|
|
|
6
|
-
__all__ = ["ModelConfig", "EnsembleConfig", "BaseLLM", "OllamaLLM", "LLMEnsemble"]
|
|
6
|
+
__all__ = ["ModelConfig", "EnsembleConfig", "BaseLLM", "OllamaLLM", "LLMEnsemble", "start_ollama"]
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import shutil
|
|
3
|
+
import subprocess
|
|
4
|
+
import time
|
|
5
|
+
from functools import cache
|
|
6
|
+
|
|
7
|
+
from ollama import Client, ResponseError
|
|
8
|
+
|
|
9
|
+
from ..telemetry import log
|
|
10
|
+
from .base import BaseLLM
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@cache
|
|
14
|
+
def _gpu_available() -> bool:
|
|
15
|
+
if not shutil.which("nvidia-smi"):
|
|
16
|
+
return False
|
|
17
|
+
try:
|
|
18
|
+
return subprocess.run(["nvidia-smi"], capture_output=True, timeout=2).returncode == 0
|
|
19
|
+
except Exception:
|
|
20
|
+
return False
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def start_ollama(host: str = "127.0.0.1:11434", *, wait: float = 5.0) -> None:
|
|
24
|
+
"""Start an ollama daemon with GPU-aware optimizations. No-op if one is already running."""
|
|
25
|
+
for prefix in ("http://", "https://"):
|
|
26
|
+
if host.startswith(prefix):
|
|
27
|
+
host = host[len(prefix):]
|
|
28
|
+
try:
|
|
29
|
+
Client(host=f"http://{host}").list()
|
|
30
|
+
log.info("[ollama] server already running on %s", host)
|
|
31
|
+
return
|
|
32
|
+
except Exception:
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
env = os.environ.copy()
|
|
36
|
+
env["OLLAMA_HOST"] = host
|
|
37
|
+
if _gpu_available():
|
|
38
|
+
env.setdefault("OLLAMA_FLASH_ATTENTION", "1")
|
|
39
|
+
env.setdefault("OLLAMA_KV_CACHE_TYPE", "q8_0")
|
|
40
|
+
env.setdefault("OLLAMA_NUM_PARALLEL", "4")
|
|
41
|
+
env.setdefault("OLLAMA_MAX_LOADED_MODELS", "2")
|
|
42
|
+
log.info("[ollama] starting server in [bold]GPU[/] mode (flash_attn, q8_0 kv-cache, parallel=4, max_loaded=2)")
|
|
43
|
+
else:
|
|
44
|
+
log.info("[ollama] starting server in [bold]CPU[/] mode")
|
|
45
|
+
|
|
46
|
+
path = shutil.which("ollama") or "/usr/local/bin/ollama"
|
|
47
|
+
subprocess.Popen([path, "serve"], env=env,
|
|
48
|
+
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
49
|
+
time.sleep(wait)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class OllamaLLM(BaseLLM):
|
|
53
|
+
def __init__(self, model_config, *, host: str = "http://localhost:11434", timeout: float = 600.0, system_prompt: str | None = None):
|
|
54
|
+
self.cfg = model_config
|
|
55
|
+
self.system_prompt = system_prompt
|
|
56
|
+
self.client = Client(host=host, timeout=timeout)
|
|
57
|
+
self._gpu = _gpu_available()
|
|
58
|
+
try:
|
|
59
|
+
self.client.list()
|
|
60
|
+
except Exception:
|
|
61
|
+
start_ollama(host=host)
|
|
62
|
+
self.client = Client(host=host, timeout=timeout)
|
|
63
|
+
log.info("[ollama] %s → [bold]%s[/] mode", self.cfg.name, "GPU" if self._gpu else "CPU")
|
|
64
|
+
self._ensure_model()
|
|
65
|
+
|
|
66
|
+
def _ensure_model(self):
|
|
67
|
+
try:
|
|
68
|
+
self.client.show(self.cfg.name)
|
|
69
|
+
except ResponseError:
|
|
70
|
+
log.info("[ollama] pulling [bold]%s[/]...", self.cfg.name)
|
|
71
|
+
self.client.pull(self.cfg.name)
|
|
72
|
+
|
|
73
|
+
def generate(self, prompt: str) -> str:
|
|
74
|
+
try:
|
|
75
|
+
return self._generate(prompt)
|
|
76
|
+
except Exception:
|
|
77
|
+
log.exception("ollama generate failed for model=%s", self.cfg.name)
|
|
78
|
+
raise
|
|
79
|
+
|
|
80
|
+
def _options(self) -> dict:
|
|
81
|
+
opts = {
|
|
82
|
+
"temperature": self.cfg.temperature,
|
|
83
|
+
"num_ctx": self.cfg.num_ctx,
|
|
84
|
+
"flash_attn": self.cfg.flash_attention and self._gpu,
|
|
85
|
+
"num_gpu": -1 if self._gpu else 0,
|
|
86
|
+
"num_thread": 0 if self._gpu else (os.cpu_count() or 4),
|
|
87
|
+
}
|
|
88
|
+
opts.update(self.cfg.options)
|
|
89
|
+
return opts
|
|
90
|
+
|
|
91
|
+
def _generate(self, prompt: str) -> str:
|
|
92
|
+
resp = self.client.generate(
|
|
93
|
+
model=self.cfg.name,
|
|
94
|
+
prompt=prompt,
|
|
95
|
+
system=self.system_prompt,
|
|
96
|
+
options=self._options(),
|
|
97
|
+
keep_alive="1h",
|
|
98
|
+
stream=False,
|
|
99
|
+
)
|
|
100
|
+
return resp.response
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "fastevolve"
|
|
3
|
-
version = "0.3.
|
|
3
|
+
version = "0.3.3"
|
|
4
4
|
description = "Minimal open-source AlphaEvolve: LLM-driven program evolution with MAP-Elites islands, cascade evaluation, and a local Ollama ensemble."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
from ollama import Client, ResponseError
|
|
2
|
-
|
|
3
|
-
from ..telemetry import log
|
|
4
|
-
from .base import BaseLLM
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class OllamaLLM(BaseLLM):
|
|
8
|
-
def __init__(self, model_config, *, host: str = "http://localhost:11434", timeout: float = 600.0, system_prompt: str | None = None):
|
|
9
|
-
self.cfg = model_config
|
|
10
|
-
self.system_prompt = system_prompt
|
|
11
|
-
self.client = Client(host=host, timeout=timeout)
|
|
12
|
-
self._ensure_model()
|
|
13
|
-
|
|
14
|
-
def _ensure_model(self):
|
|
15
|
-
try:
|
|
16
|
-
self.client.show(self.cfg.name)
|
|
17
|
-
except ResponseError:
|
|
18
|
-
log.info("[ollama] pulling [bold]%s[/]...", self.cfg.name)
|
|
19
|
-
self.client.pull(self.cfg.name)
|
|
20
|
-
|
|
21
|
-
def generate(self, prompt: str) -> str:
|
|
22
|
-
try:
|
|
23
|
-
return self._generate(prompt)
|
|
24
|
-
except Exception:
|
|
25
|
-
log.exception("ollama generate failed for model=%s", self.cfg.name)
|
|
26
|
-
raise
|
|
27
|
-
|
|
28
|
-
def _options(self) -> dict:
|
|
29
|
-
opts = {
|
|
30
|
-
"temperature": self.cfg.temperature,
|
|
31
|
-
"num_ctx": self.cfg.num_ctx,
|
|
32
|
-
"flash_attn": self.cfg.flash_attention,
|
|
33
|
-
}
|
|
34
|
-
opts.update(self.cfg.options)
|
|
35
|
-
return opts
|
|
36
|
-
|
|
37
|
-
def _generate(self, prompt: str) -> str:
|
|
38
|
-
resp = self.client.generate(
|
|
39
|
-
model=self.cfg.name,
|
|
40
|
-
prompt=prompt,
|
|
41
|
-
system=self.system_prompt,
|
|
42
|
-
options=self._options(),
|
|
43
|
-
stream=False,
|
|
44
|
-
)
|
|
45
|
-
return resp.response
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|