Skip to content

Commit a9d3400

Browse files
DSPy - Bugfixes and update to dspy-ai (#246)
* Bugfix DSPy instrumentation * Add example for parallel execution * Bump version
1 parent fc1b186 commit a9d3400

File tree

4 files changed

+98
-39
lines changed

4 files changed

+98
-39
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import dspy
2+
from dspy.datasets.gsm8k import GSM8K, gsm8k_metric
3+
from dspy.teleprompt import BootstrapFewShot
4+
from concurrent.futures import ThreadPoolExecutor
5+
from opentelemetry.context import get_current, attach, detach
6+
7+
# flake8: noqa
8+
from langtrace_python_sdk import langtrace, with_langtrace_root_span
9+
10+
langtrace.init()
11+
12+
turbo = dspy.OpenAI(model="gpt-3.5-turbo", max_tokens=250)
13+
dspy.settings.configure(lm=turbo)
14+
15+
# Load math questions from the GSM8K dataset
16+
gsm8k = GSM8K()
17+
gsm8k_trainset, gsm8k_devset = gsm8k.train[:10], gsm8k.dev[:10]
18+
19+
class CoT(dspy.Module):
20+
def __init__(self):
21+
super().__init__()
22+
self.prog = dspy.ChainOfThought("question -> answer")
23+
24+
def forward(self, question):
25+
return self.prog(question=question)
26+
27+
@with_langtrace_root_span(name="parallel_example")
28+
def example():
29+
# Set up the optimizer: we want to "bootstrap" (i.e., self-generate) 4-shot examples of our CoT program.
30+
config = dict(max_bootstrapped_demos=4, max_labeled_demos=4)
31+
32+
# Optimize! Use the `gsm8k_metric` here. In general, the metric is going to tell the optimizer how well it's doing.
33+
teleprompter = BootstrapFewShot(metric=gsm8k_metric, **config)
34+
optimized_cot = teleprompter.compile(CoT(), trainset=gsm8k_trainset)
35+
36+
questions = [
37+
"What is the cosine of 0?",
38+
"What is the tangent of 0?",
39+
]
40+
41+
current_context = get_current()
42+
43+
def run_with_context(context, func, *args, **kwargs):
44+
token = attach(context)
45+
try:
46+
return func(*args, **kwargs)
47+
finally:
48+
detach(token)
49+
50+
with ThreadPoolExecutor(max_workers=2) as executor:
51+
futures = [executor.submit(run_with_context, current_context, optimized_cot, question=q) for q in questions]
52+
53+
for future in futures:
54+
ans = future.result()
55+
print(ans)
56+
57+
58+
if __name__ == "__main__":
59+
example()

src/langtrace_python_sdk/instrumentation/dspy/instrumentation.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ class DspyInstrumentation(BaseInstrumentor):
2727
The DspyInstrumentor class represents the DSPy instrumentation"""
2828

2929
def instrumentation_dependencies(self) -> Collection[str]:
30-
return ["dspy >= 0.1.5"]
30+
return ["dspy-ai >= 2.0.0"]
3131

3232
def _instrument(self, **kwargs):
3333
tracer_provider = kwargs.get("tracer_provider")
3434
tracer = get_tracer(__name__, "", tracer_provider)
35-
version = v("dspy")
35+
version = v("dspy-ai")
3636
_W(
3737
"dspy.teleprompt.bootstrap",
3838
"BootstrapFewShot.compile",

src/langtrace_python_sdk/instrumentation/dspy/patch.py

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -39,25 +39,25 @@ def traced_method(wrapped, instance, args, kwargs):
3939
),
4040
}
4141
span_attributes["dspy.optimizer.module.prog"] = json.dumps(prog)
42-
if "metric" in instance and instance.metric:
43-
span_attributes["dspy.optimizer.metric"] = instance.metric.__name__
42+
if hasattr(instance, 'metric'):
43+
span_attributes["dspy.optimizer.metric"] = getattr(instance, 'metric').__name__
4444
if kwargs.get("trainset") and len(kwargs.get("trainset")) > 0:
4545
span_attributes["dspy.optimizer.trainset"] = str(kwargs.get("trainset"))
4646
config = {}
47-
if "metric_threshold" in instance and instance.metric_threshold:
48-
config["metric_threshold"] = instance.metric_threshold
49-
if "teacher_settings" in instance and instance.teacher_settings:
50-
config["teacher_settings"] = instance.teacher_settings
51-
if "max_bootstrapped_demos" in instance and instance.max_bootstrapped_demos:
52-
config["max_bootstrapped_demos"] = instance.max_bootstrapped_demos
53-
if "max_labeled_demos" in instance and instance.max_labeled_demos:
54-
config["max_labeled_demos"] = instance.max_labeled_demos
55-
if "max_rounds" in instance and instance.max_rounds:
56-
config["max_rounds"] = instance.max_rounds
57-
if "max_errors" in instance and instance.max_errors:
58-
config["max_errors"] = instance.max_errors
59-
if "error_count" in instance and instance.error_count:
60-
config["error_count"] = instance.error_count
47+
if hasattr(instance, 'metric_threshold'):
48+
config["metric_threshold"] = getattr(instance, 'metric_threshold')
49+
if hasattr(instance, 'teacher_settings'):
50+
config["teacher_settings"] = getattr(instance, 'teacher_settings')
51+
if hasattr(instance, 'max_bootstrapped_demos'):
52+
config["max_bootstrapped_demos"] = getattr(instance, 'max_bootstrapped_demos')
53+
if hasattr(instance, 'max_labeled_demos'):
54+
config["max_labeled_demos"] = getattr(instance, 'max_labeled_demos')
55+
if hasattr(instance, 'max_rounds'):
56+
config["max_rounds"] = getattr(instance, 'max_rounds')
57+
if hasattr(instance, 'max_steps'):
58+
config["max_errors"] = getattr(instance, 'max_errors')
59+
if hasattr(instance, 'error_count'):
60+
config["error_count"] = getattr(instance, 'error_count')
6161
if config and len(config) > 0:
6262
span_attributes["dspy.optimizer.config"] = json.dumps(config)
6363

@@ -147,30 +147,30 @@ def traced_method(wrapped, instance, args, kwargs):
147147
**(extra_attributes if extra_attributes is not None else {}),
148148
}
149149

150-
if "devset" in instance and instance.devset is not None:
151-
span_attributes["dspy.evaluate.devset"] = str(instance.devset)
152-
if "display" in instance and instance.display is not None:
153-
span_attributes["dspy.evaluate.display"] = str(instance.display)
154-
if "num_threads" in instance and instance.num_threads is not None:
155-
span_attributes["dspy.evaluate.num_threads"] = str(instance.num_threads)
156-
if "return_outputs" in instance and instance.return_outputs is not None:
150+
if hasattr(instance, "devset"):
151+
span_attributes["dspy.evaluate.devset"] = str(getattr(instance, "devset"))
152+
if hasattr(instance, "trainset"):
153+
span_attributes["dspy.evaluate.display"] = str(getattr(instance, "trainset"))
154+
if hasattr(instance, "num_threads"):
155+
span_attributes["dspy.evaluate.num_threads"] = str(getattr(instance, "num_threads"))
156+
if hasattr(instance, "return_outputs"):
157157
span_attributes["dspy.evaluate.return_outputs"] = str(
158-
instance.return_outputs
158+
getattr(instance, "return_outputs")
159159
)
160-
if "display_table" in instance and instance.display_table is not None:
161-
span_attributes["dspy.evaluate.display_table"] = str(instance.display_table)
162-
if "display_progress" in instance and instance.display_progress is not None:
160+
if hasattr(instance, "display_table"):
161+
span_attributes["dspy.evaluate.display_table"] = str(getattr(instance, "display_table"))
162+
if hasattr(instance, "display_progress"):
163163
span_attributes["dspy.evaluate.display_progress"] = str(
164-
instance.display_progress
164+
getattr(instance, "display_progress")
165165
)
166-
if "metric" in instance and instance.metric is not None:
167-
span_attributes["dspy.evaluate.metric"] = instance.metric.__name__
168-
if "error_count" in instance and instance.error_count is not None:
169-
span_attributes["dspy.evaluate.error_count"] = str(instance.error_count)
170-
if "error_lock" in instance and instance.error_lock is not None:
171-
span_attributes["dspy.evaluate.error_lock"] = str(instance.error_lock)
172-
if "max_errors" in instance and instance.max_errors is not None:
173-
span_attributes["dspy.evaluate.max_errors"] = str(instance.max_errors)
166+
if hasattr(instance, "metric"):
167+
span_attributes["dspy.evaluate.metric"] = getattr(instance, "metric").__name__
168+
if hasattr(instance, "error_count"):
169+
span_attributes["dspy.evaluate.error_count"] = str(getattr(instance, "error_count"))
170+
if hasattr(instance, "error_lock"):
171+
span_attributes["dspy.evaluate.error_lock"] = str(getattr(instance, "error_lock"))
172+
if hasattr(instance, "max_errors"):
173+
span_attributes["dspy.evaluate.max_errors"] = str(getattr(instance, "max_errors"))
174174
if args and len(args) > 0:
175175
span_attributes["dspy.evaluate.args"] = str(args)
176176

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "2.2.1"
1+
__version__ = "2.2.2"

0 commit comments

Comments
 (0)