maodd commited on
Commit
974b41a
·
verified ·
1 Parent(s): 741cd88

Re-add token-aware pacing for llama-3.1-8b-instant's tight TPM

Browse files

8b model's 6000 TPM cap is tighter in practice than 70b's - a single call already costs 2400-4000 tokens before any tool output. Native requests_per_minute can't account for token size. Re-add TokenPacer step_callback, drop redundant add_base_tools DuckDuckGo tool to shrink per-call overhead.

Files changed (1) hide show
  1. app.py +40 -2
app.py CHANGED
@@ -1,5 +1,7 @@
1
  import os
2
  import tempfile
 
 
3
  import gradio as gr
4
  import requests
5
  import inspect
@@ -39,6 +41,37 @@ If you are asked for a comma separated list, apply the above rules to each eleme
39
  Work efficiently: if a search or lookup doesn't find what you need after 1-2 tries, try a meaningfully different approach rather than repeating similar queries, and give your best-guess final_answer rather than exhausting all steps.
40
  """
41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  class MemoryTrimmer:
43
  """
44
  Step_callback that collapses old tool outputs in the agent's memory.
@@ -94,13 +127,18 @@ class BasicAgent:
94
  VisitWebpageTool(max_output_length=3000), # default 40000 chars blows the TPM budget in one call
95
  WikipediaSearchTool(content_type="summary"), # "text" (default) returns the full article
96
  ],
97
- add_base_tools=True, # adds DuckDuckGo search + Whisper audio transcriber
 
 
98
  additional_authorized_imports=[
99
  "pandas", "numpy", "math", "re", "json", "itertools",
100
  "collections", "statistics", "datetime", "io", "openpyxl", "PIL",
101
  ],
102
  max_steps=7, # keep runs short: growing history otherwise blows the TPM budget by step ~6
103
- step_callbacks=[MemoryTrimmer()],
 
 
 
104
  )
105
  print("BasicAgent initialized.")
106
 
 
1
  import os
2
  import tempfile
3
+ import time
4
+ from collections import deque
5
  import gradio as gr
6
  import requests
7
  import inspect
 
41
  Work efficiently: if a search or lookup doesn't find what you need after 1-2 tries, try a meaningfully different approach rather than repeating similar queries, and give your best-guess final_answer rather than exhausting all steps.
42
  """
43
 
44
+ class TokenPacer:
45
+ """
46
+ Step_callback that tracks actual token usage per step in a trailing 60s
47
+ window and sleeps as needed to stay under a tokens-per-minute budget.
48
+ Necessary because a single call's fixed overhead (system prompt + tool
49
+ schemas + question, before any tool output) already runs 2,400-4,000
50
+ tokens on this agent - so llama-3.1-8b-instant's free-tier TPM cap (6000)
51
+ only fits ~1-2 calls per minute regardless of request frequency, which
52
+ smolagents' native requests_per_minute throttle can't account for since
53
+ it only paces call count, not size.
54
+ """
55
+ def __init__(self, tokens_per_minute_budget: int = 5000):
56
+ self.tokens_per_minute_budget = tokens_per_minute_budget
57
+ self._usage_window: deque[tuple[float, int]] = deque()
58
+
59
+ def __call__(self, memory_step: ActionStep, agent: CodeAgent) -> None:
60
+ now = time.monotonic()
61
+ usage = getattr(memory_step, "token_usage", None)
62
+ tokens = (usage.input_tokens + usage.output_tokens) if usage else 0
63
+ self._usage_window.append((now, tokens))
64
+ cutoff = now - 60
65
+ while self._usage_window and self._usage_window[0][0] < cutoff:
66
+ self._usage_window.popleft()
67
+ window_tokens = sum(t for _, t in self._usage_window)
68
+ if window_tokens > self.tokens_per_minute_budget and self._usage_window:
69
+ wait = 60 - (now - self._usage_window[0][0]) + 0.5
70
+ if wait > 0:
71
+ print(f"Token pacer: {window_tokens} tokens in the last 60s (budget {self.tokens_per_minute_budget}), sleeping {wait:.1f}s")
72
+ time.sleep(wait)
73
+
74
+
75
  class MemoryTrimmer:
76
  """
77
  Step_callback that collapses old tool outputs in the agent's memory.
 
127
  VisitWebpageTool(max_output_length=3000), # default 40000 chars blows the TPM budget in one call
128
  WikipediaSearchTool(content_type="summary"), # "text" (default) returns the full article
129
  ],
130
+ # add_base_tools=True would add a duplicate DuckDuckGo search tool -
131
+ # every tool's schema is baked into the system prompt on every call,
132
+ # and that fixed overhead is what's blowing the 6000 TPM budget.
133
  additional_authorized_imports=[
134
  "pandas", "numpy", "math", "re", "json", "itertools",
135
  "collections", "statistics", "datetime", "io", "openpyxl", "PIL",
136
  ],
137
  max_steps=7, # keep runs short: growing history otherwise blows the TPM budget by step ~6
138
+ step_callbacks=[
139
+ MemoryTrimmer(),
140
+ TokenPacer(tokens_per_minute_budget=int(os.getenv("RATE_LIMIT_TOKENS_PER_MINUTE", "5000"))),
141
+ ],
142
  )
143
  print("BasicAgent initialized.")
144