This project is an implementation and expansion of an interesting approach to structured reasoning using DAGs (Directed Acyclic Graphs) through the use of structured outputs (Instructor Library) This is specifically for the use during Test Time Compute models such as gpt-o1/o1-mini/o1-pro
Original prompt by @mrsiipa
DAG of Thought provides a framework for analyzing and controlling how language models reason by:
- Capturing the step-by-step thought process during inference
- Visualizing reasoning patterns and dependencies as DAG diagrams
- Analyzing thought flows to understand model behavior
- Using guard rails to guide and constrain reasoning paths
- Enabling systematic observation and steering of language model reasoning
TASK = "Design an optimized CUDA kernel implementation for softmax that maximizes throughput while maintaining numerical stability"
GUARDRAILS = [
GuardRail(
name="Numerical Stability",
description="Must maintain numerical stability (handling overflow/underflow)"
),
GuardRail(
name="Memory Usage",
description="Maximum shared memory usage of 48KB per block"
),
GuardRail(
name="Batch Handling",
description="Must handle variable batch sizes efficiently"
),
GuardRail(
name="Performance",
description="Must outperform naive implementation by at least 100x"
),
GuardRail(
name="Dependencies",
description="Cannot use external CUDA libraries (only basic CUDA primitives)"
)
]In revisiting and extending our exploration, we see that:
- Numerical stability hinges on a robust max-subtraction method, possibly refined with warp-level primitives to reduce overhead
- A single-pass approach can reduce global memory traffic, but requires careful synchronization and design of warp-level reductions
- Multi-pass segmented approaches may be necessary for extremely large dimensions, keeping shared memory usage within 48KB per block
- Efficiently coordinating thread blocks for variable batch sizes ensures each batch dimension is handled independently, respecting memory boundaries and delivering high throughput
- These advanced optimizations, if implemented carefully with attention to kernel launch configuration, warp synchronization, and shared memory utilization, further boost performance beyond the initial two-pass approach while still meeting the constraints of numerical stability, memory usage, and dependency limitations
- Is there a practical upper bound on dimension size where multi-pass segmented softmax is more advantageous than a single-pass approach?
- Could mixed precision (e.g., FP16 for intermediate exponentials) maintain stability while improving throughput further?
- Is conclusion premature? No
- Reason: conclusion NOT premature
DAGofThought/
├── utils/
│ ├── build_mermaid_diagram.py # Diagram generation utilities
│ └── make_gpt_pro_prompt.py # Prompt construction tools
├── models/
│ ├── input_models.py # Input data structures
│ └── output_models.py # Output data structures
├── prompts/
│ ├── in_depth_thinking_system_prompt.md # System prompt template
│ └── format_structured_reasoning_user_prompt.py # User prompt formatter
├── data/
│ └── outputs/ # Generated outputs directory
├── Notebooks/
│ ├── 0_generate_thought_dag.ipynb # DAG generation workflow
│ └── 1_process_responses_for_report.ipynb # Response analysis
- Basic building blocks of the reasoning process
- Groups related atomic steps
- Provides foundation for higher-level thoughts
- Individual units of reasoning
- Must flow logically from previous steps
- Can represent either progress or dead ends
- Complete reasoning units built on foundation observations
- Can include multiple atomic steps
- May reference guard rails and previous thoughts
- Constraints and guidance for the reasoning process
- Help maintain focus and relevance
- Can be customized for specific domains
The project can generate visual representations of reasoning processes using Mermaid diagrams, showing:
- Relationships between thoughts
- Foundation observation hierarchies
- Step-by-step reasoning flows
All reasoning processes are structured as JSON objects with:
- Clear hierarchies
- Traceable relationships
- Standardized formats
Implements a flexible guard rail system that:
- Enforces constraints
- Guides reasoning paths
- Maintains relevance to goals
- Clone the repository:
git clone https://github.com/yourusername/DAGofThought.git
cd DAGofThought- Copy the environment file and add your OpenAI API key:
cp .env.example .env
# Edit .env and add your OPENAI_API_KEY- Install dependencies:
pip install -r requirements.txt- Configure your task and guard rails in
0_generate_thought_dag.ipynb - Generate thought DAGs:
response = generate_structured_reasoning(TASK, GUARDRAILS, GuardRailEnum)- Visualize results:
diagram_text = build_mermaid_diagram(response.model_dump())Use 1_process_responses_for_report.ipynb to:
- Analyze generated responses
- Create summary reports
- Export visualizations
- Define new guard rails in your experiment:
GUARDRAILS = [
GuardRail(
name="Custom Rule",
description="Your constraint description"
),
# Add more as needed
]- Create corresponding enum entries:
GuardRailEnum = Enum('GuardRailEnum', {
name.upper().replace(' ', '_'): name
for guardrail in GUARDRAILS
for name in [guardrail.name]
})The project includes special handling for GPT Pro:
- Custom prompt formatting
- Response processing
- Timeout handling
Built-in tools for:
- Processing multiple responses
- Generating summary reports
- Creating comparative analyses
Contributions are welcome! Please feel free to submit a Pull Request.
This project is based on:
- Original concept by @mrsiipa
- Initial implementation by Maharshi Pandya