Skip to content

Commit e253be4

Browse files
authored
Merge pull request #261 from totoluo/feat-export-trace
feature: Add evolution trace logging for RL training support
2 parents 7630298 + 30e8a65 commit e253be4

File tree

7 files changed

+1678
-3
lines changed

7 files changed

+1678
-3
lines changed

configs/default_config.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,14 @@ evaluator:
159159
# LLM-based feedback (experimental)
160160
use_llm_feedback: false # Use LLM to evaluate code quality
161161
llm_feedback_weight: 0.1 # Weight for LLM feedback in final score
162+
163+
# Evolution trace configuration
164+
# Logs detailed traces of program evolution for RL training and analysis
165+
evolution_trace:
166+
enabled: false # Enable evolution trace logging
167+
format: 'jsonl' # Output format: 'jsonl', 'json', or 'hdf5'
168+
include_code: false # Include full program code in traces
169+
include_prompts: true # Include prompts and LLM responses
170+
output_path: null # Path for trace output (defaults to output_dir/evolution_trace.{format})
171+
buffer_size: 10 # Number of traces to buffer before writing
172+
compress: false # Compress output file (jsonl only)

openevolve/config.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,19 @@ class EvaluatorConfig:
313313
max_artifact_storage: int = 100 * 1024 * 1024 # 100MB per program
314314

315315

316+
@dataclass
317+
class EvolutionTraceConfig:
318+
"""Configuration for evolution trace logging"""
319+
320+
enabled: bool = False
321+
format: str = "jsonl" # Options: "jsonl", "json", "hdf5"
322+
include_code: bool = False
323+
include_prompts: bool = True
324+
output_path: Optional[str] = None
325+
buffer_size: int = 10
326+
compress: bool = False
327+
328+
316329
@dataclass
317330
class Config:
318331
"""Master configuration for OpenEvolve"""
@@ -330,6 +343,7 @@ class Config:
330343
prompt: PromptConfig = field(default_factory=PromptConfig)
331344
database: DatabaseConfig = field(default_factory=DatabaseConfig)
332345
evaluator: EvaluatorConfig = field(default_factory=EvaluatorConfig)
346+
evolution_trace: EvolutionTraceConfig = field(default_factory=EvolutionTraceConfig)
333347

334348
# Evolution settings
335349
diff_based_evolution: bool = True
@@ -355,7 +369,7 @@ def from_dict(cls, config_dict: Dict[str, Any]) -> "Config":
355369

356370
# Update top-level fields
357371
for key, value in config_dict.items():
358-
if key not in ["llm", "prompt", "database", "evaluator"] and hasattr(config, key):
372+
if key not in ["llm", "prompt", "database", "evaluator", "evolution_trace"] and hasattr(config, key):
359373
setattr(config, key, value)
360374

361375
# Update nested configs
@@ -378,6 +392,8 @@ def from_dict(cls, config_dict: Dict[str, Any]) -> "Config":
378392
config.database.random_seed = config.random_seed
379393
if "evaluator" in config_dict:
380394
config.evaluator = EvaluatorConfig(**config_dict["evaluator"])
395+
if "evolution_trace" in config_dict:
396+
config.evolution_trace = EvolutionTraceConfig(**config_dict["evolution_trace"])
381397

382398
return config
383399

@@ -446,6 +462,15 @@ def to_dict(self) -> Dict[str, Any]:
446462
"use_llm_feedback": self.evaluator.use_llm_feedback,
447463
"llm_feedback_weight": self.evaluator.llm_feedback_weight,
448464
},
465+
"evolution_trace": {
466+
"enabled": self.evolution_trace.enabled,
467+
"format": self.evolution_trace.format,
468+
"include_code": self.evolution_trace.include_code,
469+
"include_prompts": self.evolution_trace.include_prompts,
470+
"output_path": self.evolution_trace.output_path,
471+
"buffer_size": self.evolution_trace.buffer_size,
472+
"compress": self.evolution_trace.compress,
473+
},
449474
# Evolution settings
450475
"diff_based_evolution": self.diff_based_evolution,
451476
"max_code_length": self.max_code_length,

openevolve/controller.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from openevolve.config import Config, load_config
1515
from openevolve.database import Program, ProgramDatabase
1616
from openevolve.evaluator import Evaluator
17+
from openevolve.evolution_trace import EvolutionTracer
1718
from openevolve.llm.ensemble import LLMEnsemble
1819
from openevolve.prompt.sampler import PromptSampler
1920
from openevolve.process_parallel import ProcessParallelController
@@ -163,6 +164,29 @@ def __init__(
163164

164165
logger.info(f"Initialized OpenEvolve with {initial_program_path}")
165166

167+
# Initialize evolution tracer
168+
if self.config.evolution_trace.enabled:
169+
trace_output_path = self.config.evolution_trace.output_path
170+
if not trace_output_path:
171+
# Default to output_dir/evolution_trace.{format}
172+
trace_output_path = os.path.join(
173+
self.output_dir,
174+
f"evolution_trace.{self.config.evolution_trace.format}"
175+
)
176+
177+
self.evolution_tracer = EvolutionTracer(
178+
output_path=trace_output_path,
179+
format=self.config.evolution_trace.format,
180+
include_code=self.config.evolution_trace.include_code,
181+
include_prompts=self.config.evolution_trace.include_prompts,
182+
enabled=True,
183+
buffer_size=self.config.evolution_trace.buffer_size,
184+
compress=self.config.evolution_trace.compress
185+
)
186+
logger.info(f"Evolution tracing enabled: {trace_output_path}")
187+
else:
188+
self.evolution_tracer = None
189+
166190
# Initialize improved parallel processing components
167191
self.parallel_controller = None
168192

@@ -276,7 +300,7 @@ async def run(
276300
# Initialize improved parallel processing
277301
try:
278302
self.parallel_controller = ProcessParallelController(
279-
self.config, self.evaluation_file, self.database
303+
self.config, self.evaluation_file, self.database, self.evolution_tracer
280304
)
281305

282306
# Set up signal handlers for graceful shutdown
@@ -319,6 +343,11 @@ def force_exit_handler(signum, frame):
319343
if self.parallel_controller:
320344
self.parallel_controller.stop()
321345
self.parallel_controller = None
346+
347+
# Close evolution tracer
348+
if self.evolution_tracer:
349+
self.evolution_tracer.close()
350+
logger.info("Evolution tracer closed")
322351

323352
# Get the best program
324353
best_program = None

0 commit comments

Comments
 (0)