Skip to content

Commit b9943b8

Browse files
authored
Merge pull request #51 from AI-Hypercomputer/shangkun-fix-autotune
feat: enhance autotuning process with ApplyBestConfigAgent and update…
2 parents d43d848 + 8c379c5 commit b9943b8

5 files changed

Lines changed: 106 additions & 22 deletions

File tree

MaxKernel/auto_agent/agent_client/auto_agent_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import requests
66

7-
REQUEST_TIMEOUT = 60 * 60 * 3
7+
REQUEST_TIMEOUT = 60 * 60 * 5
88

99

1010
# Configure logging

MaxKernel/auto_agent/custom_types.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,40 @@
11
import logging
2+
from functools import cached_property
23
from typing import AsyncGenerator
34

45
from google.adk.agents import LlmAgent
56
from google.adk.agents.invocation_context import InvocationContext
67
from google.adk.events import Event, EventActions
78
from google.adk.models.google_llm import Gemini
8-
from google.genai import types
9+
from google.genai import Client, types
910

1011
from auto_agent.constants import (
1112
MODEL_NAME,
1213
)
1314

1415

16+
class TimeoutGemini(Gemini):
17+
@cached_property
18+
def api_client(self) -> Client:
19+
base_url, api_version = self._base_url_and_api_version
20+
kwargs_for_http_options = {
21+
"headers": self._tracking_headers(),
22+
"retry_options": self.retry_options,
23+
"base_url": base_url,
24+
"timeout": 240000, # 240 seconds in milliseconds
25+
}
26+
if api_version:
27+
kwargs_for_http_options["api_version"] = api_version
28+
29+
kwargs = {
30+
"http_options": types.HttpOptions(**kwargs_for_http_options),
31+
}
32+
if self.model.startswith("projects/"):
33+
kwargs["vertexai"] = True
34+
35+
return Client(**kwargs)
36+
37+
1538
class CustomLlmAgent(LlmAgent):
1639
"""Agent that allows early exit from the loop if a condition is met.
1740
@@ -22,7 +45,7 @@ def __init__(self, *args, **kwargs):
2245
"""Initialize CustomLlmAgent with automatic Gemini model (with retry) wrapping."""
2346
# If model is a string, use the pre-configured gemini_model with retry support
2447
if "model" in kwargs and isinstance(kwargs["model"], str):
25-
gemini_model = Gemini(
48+
gemini_model = TimeoutGemini(
2649
model=MODEL_NAME,
2750
retry_options=types.HttpRetryOptions(
2851
initial_delay=1,

MaxKernel/auto_agent/subagents/autotuning/agent.py

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import os
66
from typing import AsyncGenerator, Optional
77

8-
from google.adk.agents import BaseAgent, SequentialAgent
8+
from google.adk.agents import BaseAgent
99
from google.adk.agents.invocation_context import InvocationContext
1010
from google.adk.events import Event, EventActions
1111

@@ -14,6 +14,7 @@
1414
from auto_agent.custom_types import CustomLlmAgent
1515
from auto_agent.subagents.autotuning.autotune_tool import autotune_kernel
1616
from auto_agent.subagents.autotuning.prompts import (
17+
apply_best_config_prompt,
1718
autotune_prompt,
1819
summary_prompt,
1920
)
@@ -159,22 +160,69 @@ async def _run_async_impl(
159160
)
160161

161162

162-
# 3. Summarizer Agent
163+
# 3. Apply Best Config Agent
164+
apply_best_config_agent = CustomLlmAgent(
165+
name="ApplyBestConfigAgent",
166+
model=MODEL_NAME,
167+
generate_content_config=model_config,
168+
planner=thinking_planner,
169+
instruction=apply_best_config_prompt.PROMPT,
170+
description="Applies autotuning results to the optimized kernel file.",
171+
tools=[filesystem_tool_r, write_optimized_kernel_tool],
172+
)
173+
174+
175+
# 4. Summarizer Agent
163176
# This agent reads results from state and talks to the user.
164177
autotune_summary_agent = CustomLlmAgent(
165178
name="AutotuneSummaryAgent",
166179
model=MODEL_NAME,
167180
generate_content_config=model_config,
168181
planner=thinking_planner,
169182
instruction=summary_prompt.PROMPT,
170-
description="Apply and Summarizes autotuning results.",
171-
tools=[filesystem_tool_r, write_optimized_kernel_tool],
183+
description="Summarizes autotuning results.",
184+
tools=[filesystem_tool_r],
172185
output_key="autotuning_summary",
173186
)
174187

175-
autotune_agent = SequentialAgent(
176-
name="AutotuneAgent",
177-
sub_agents=[autotune_planner_agent, autotune_runner, autotune_summary_agent],
178-
)
188+
189+
class CombinedAutotuneAgent(BaseAgent):
190+
"""Chains autotuning steps and conditionally applies best config."""
191+
192+
def __init__(self, name: str):
193+
super().__init__(name=name)
194+
195+
async def _run_async_impl(
196+
self, ctx: InvocationContext
197+
) -> AsyncGenerator[Event, None]:
198+
logging.info(f"[{self.name}] Running AutotunePlannerAgent...")
199+
async for event in autotune_planner_agent.run_async(ctx):
200+
yield event
201+
202+
logging.info(f"[{self.name}] Running AutotuneRunner...")
203+
async for event in autotune_runner.run_async(ctx):
204+
yield event
205+
206+
autotune_results = ctx.session.state.get("autotune_results", {})
207+
if (
208+
autotune_results.get("status") == "success"
209+
and autotune_results.get("best_config") is not None
210+
and autotune_results.get("best_time_ms") is not None
211+
):
212+
logging.info(f"[{self.name}] Running ApplyBestConfigAgent...")
213+
async for event in apply_best_config_agent.run_async(ctx):
214+
yield event
215+
else:
216+
logging.warning(
217+
f"[{self.name}] Autotune was not successful or no best configuration"
218+
" found. Skipping ApplyBestConfigAgent."
219+
)
220+
221+
logging.info(f"[{self.name}] Running AutotuneSummaryAgent...")
222+
async for event in autotune_summary_agent.run_async(ctx):
223+
yield event
224+
225+
226+
autotune_agent = CombinedAutotuneAgent(name="AutotuneAgent")
179227

180228
__all__ = ["autotune_agent"]
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""Prompt for ApplyBestConfigAgent."""
2+
3+
PROMPT = """You are a specialized agent for applying autotuning results to a Pallas kernel file.
4+
Your goal is to read the best configuration from autotuning results and update the `optimized_kernel.py` file with these values.
5+
6+
You must:
7+
1. Use the `read_file` tool to read the autotuning specifications file at {autotune_specs_path?} to understand the code template and the placeholders that were tuned.
8+
2. Use the `read_file` tool to read the autotuning results file at {autotune_results_path?} and extract the `"best_config"` from it.
9+
3. Use the `read_file` tool to read the current optimized kernel code located at {optimized_kernel_path?}.
10+
4. Apply `"best_config"` to the optimized kernel code by:
11+
- Comparing the template structure from the specifications with the actual kernel code.
12+
- Replacing the parameter values in the kernel code with the corresponding best values found in `"best_config"` (e.g., replace `BLOCK_M = 32` with `BLOCK_M = 128` if `best_config` contains `"BLOCK_M": 128`). Ensure the formatting of the script remains valid.
13+
- Write the updated optimized kernel code back using the `restricted_write_file` tool.
14+
5. Verify the best configuration is applied correctly by reading the updated file.
15+
16+
Be precise and ensure you only change the specific parameter values identified in the best configuration.
17+
"""

MaxKernel/auto_agent/subagents/autotuning/prompts/summary_prompt.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
"""Prompt for AutotuneSummarizerAgent."""
22

33
PROMPT = """
4-
You are applying the best configuration and providing a summary of autotuning results.
4+
You are providing a summary of autotuning results.
55
6-
Your goal is to summarize the autotuning results provided below, report the best configuration and latency, and apply the best configuration if the status is success.
6+
Your goal is to summarize the autotuning results provided below, report the best configuration and latency, and verify if the best configuration was applied if the status was success.
77
88
Autotuning Results:
99
{autotune_results?}
@@ -13,20 +13,16 @@
1313
1414
### Case 1: If the status is "success"
1515
You must:
16-
1. Extract the `"best_cfg"` and `"best_time_ms"` from the results above.
17-
2. Apply `"best_cfg"` to the kernel code located at {optimized_kernel_path?} by:
18-
a. Use the `read_file` tool to read the kernel code {optimized_kernel_path?}
19-
b. Replace their configured values with the values found in `best_config` (e.g., replace `BLOCK_M = 32` with `BLOCK_M = 128` if `best_config` contains `"BLOCK_M": 128`). Ensure the formatting of the script remains valid.
20-
c. Write the updated optimized kernel code back using `restricted_write_file` tool.
21-
3. Verify the best configuration is applied correctly by reading the updated file.
22-
4. Provide a clear summary in your response. Do NOT list all tested configurations from `all_results`.
16+
1. Extract the `"best_config"` and `"best_time_ms"` from the results above.
17+
2. Verify that the best configuration was applied correctly to the kernel code by reading the file located at {optimized_kernel_path?}.
18+
3. Provide a clear summary in your response. Do NOT list all tested configurations from `all_results`.
2319
2420
### Case 2: If the status is "failed" or "error"
2521
You must:
26-
1. Report the error message and do NOT apply any configuration.
22+
1. Report the error message.
2723
2824
In all cases, you must:
29-
1. Provide a clear summary in your response. Do NOT list all tested configurations from `all_results`.
25+
Provide a clear summary in your response. Do NOT list all tested configurations from `all_results`.
3026
3127
Please use the following format for your summary:
3228
### Autotuning Results

0 commit comments

Comments
 (0)