fastevolve 0.3.2__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.
Files changed (34) hide show
  1. {fastevolve-0.3.2 → fastevolve-0.3.3}/PKG-INFO +10 -13
  2. {fastevolve-0.3.2 → fastevolve-0.3.3}/README.md +9 -12
  3. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/llm_ensemble/__init__.py +2 -2
  4. fastevolve-0.3.3/fastevolve/llm_ensemble/ollama.py +100 -0
  5. {fastevolve-0.3.2 → fastevolve-0.3.3}/pyproject.toml +1 -1
  6. {fastevolve-0.3.2 → fastevolve-0.3.3}/uv.lock +1 -1
  7. fastevolve-0.3.2/fastevolve/llm_ensemble/ollama.py +0 -45
  8. {fastevolve-0.3.2 → fastevolve-0.3.3}/.claude/settings.local.json +0 -0
  9. {fastevolve-0.3.2 → fastevolve-0.3.3}/.gitignore +0 -0
  10. {fastevolve-0.3.2 → fastevolve-0.3.3}/.python-version +0 -0
  11. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/__init__.py +0 -0
  12. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/checkpoint.py +0 -0
  13. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/config.py +0 -0
  14. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/controller.py +0 -0
  15. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/evaluator/__init__.py +0 -0
  16. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/evaluator/config.py +0 -0
  17. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/evaluator/evaluator.py +0 -0
  18. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/evaluator/result.py +0 -0
  19. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/llm_ensemble/anthropic_llm.py +0 -0
  20. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/llm_ensemble/base.py +0 -0
  21. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/llm_ensemble/config.py +0 -0
  22. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/llm_ensemble/ensemble.py +0 -0
  23. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/llm_ensemble/openai_llm.py +0 -0
  24. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/program_database/__init__.py +0 -0
  25. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/program_database/config.py +0 -0
  26. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/program_database/database.py +0 -0
  27. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/program_database/embedder.py +0 -0
  28. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/program_database/program.py +0 -0
  29. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/prompt_sampler/__init__.py +0 -0
  30. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/prompt_sampler/config.py +0 -0
  31. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/prompt_sampler/sampler.py +0 -0
  32. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/prompt_sampler/template_library.py +0 -0
  33. {fastevolve-0.3.2 → fastevolve-0.3.3}/fastevolve/telemetry.py +0 -0
  34. {fastevolve-0.3.2 → 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.2
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
@@ -179,22 +179,19 @@ print(result.best.code)
179
179
 
180
180
  ### Google Colab (with Ollama)
181
181
 
182
- Ollama can run on Colab if you install it, start the daemon in the background, and pull a small model. Use a GPU runtime (`Runtime Change runtime type T4 GPU`) for any model bigger than ~1B parameters.
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.
183
185
 
184
186
  ```python
185
- # 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
186
189
  !curl -fsSL https://ollama.com/install.sh | sh
187
- !pip install -q fastevolve
188
-
189
- # 2. Start the ollama daemon in the background
190
- import subprocess, time
191
- subprocess.Popen(["ollama", "serve"])
192
- time.sleep(5) # give it a moment to bind to port 11434
193
-
194
- # 3. Pull a small model (qwen2.5:0.5b is ~400 MB and fits the free CPU runtime)
195
- !ollama pull qwen2.5:0.5b
190
+ !pip install uv
191
+ !uv pip install -q fastevolve
196
192
 
197
- # 4. Run fastevolve as usual
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.
198
195
  from fastevolve import Config, Controller
199
196
  from fastevolve.llm_ensemble import ModelConfig
200
197
 
@@ -149,22 +149,19 @@ print(result.best.code)
149
149
 
150
150
  ### Google Colab (with Ollama)
151
151
 
152
- Ollama can run on Colab if you install it, start the daemon in the background, and pull a small model. Use a GPU runtime (`Runtime Change runtime type T4 GPU`) for any model bigger than ~1B parameters.
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.
153
155
 
154
156
  ```python
155
- # 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
156
159
  !curl -fsSL https://ollama.com/install.sh | sh
157
- !pip install -q fastevolve
158
-
159
- # 2. Start the ollama daemon in the background
160
- import subprocess, time
161
- subprocess.Popen(["ollama", "serve"])
162
- time.sleep(5) # give it a moment to bind to port 11434
163
-
164
- # 3. Pull a small model (qwen2.5:0.5b is ~400 MB and fits the free CPU runtime)
165
- !ollama pull qwen2.5:0.5b
160
+ !pip install uv
161
+ !uv pip install -q fastevolve
166
162
 
167
- # 4. Run fastevolve as usual
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.
168
165
  from fastevolve import Config, Controller
169
166
  from fastevolve.llm_ensemble import ModelConfig
170
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.2"
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"
@@ -81,7 +81,7 @@ wheels = [
81
81
 
82
82
  [[package]]
83
83
  name = "fastevolve"
84
- version = "0.3.2"
84
+ version = "0.3.3"
85
85
  source = { editable = "." }
86
86
  dependencies = [
87
87
  { name = "ollama" },
@@ -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