Delving into DSPy: A Framework for Programming Language Models

Siddharth Sudhakar
Accredian
Published in
4 min readJun 28, 2024
Image Source: DSPy Documentation | DSPy (dspy-docs.vercel.app)

Language models (LMs) such as GPT-4 have become extremely popular. They can generate text, translate languages, produce various types of creative content, and provide informative answers to questions. Nevertheless, the method of interaction with these powerful models is rapidly evolving. In this article, let’s delve into DSPy, an innovative framework Stanford developed that is transforming how we interact with LMs. We will discuss DSPy’s key concepts, advantages, and impact on LMs.

What is DSPy?

DSPy is a toolkit that lets you build structured programs to guide language models instead of relying on complex prompts.

Say you have an idea that could benefit from LMs, but you are struggling to achieve your goal with them. Determining the proper prompts and obtaining consistent, reliable outputs can be challenging. This difficulty can cause you to get bogged down in the details instead of focusing on your primary goals.

Now, DSPy can make your life easier by giving the LM clear instructions in a language it understands. It offers a unique approach by allowing you to concentrate on defining your program’s high-level logic; the LM tuning is left to specialized “optimizers.”

DSPy doesn’t work any magic with the language model. It uses various prompt templates behind the scenes, making them accessible as “signatures.” Additionally, DSPy provides features such as module settings, assertion-based backtracking, and automatic prompt optimization.

Cracking the DSPy Code: Key Terms Explained

  • Module: The basic building block in DSPy. Modules encapsulate instructions for specific tasks, like summarizing or translating text.
  • Compiler: The DSPy compiler translates your Python-based program into instructions the LM can understand and execute efficiently.
  • Signature: Defines the input and output types of a module, ensuring compatibility between different modules in a DSPy program.
  • Optimizer (Teleprompter): A component of DSPy that fine-tunes the compiled program for the specific LM you’re using, maximizing performance and accuracy.
  • Pipeline: A sequence of connected modules that work together to achieve a complex task. For example, a pipeline might summarize an article, translate it, and then generate questions about it.
An explanation of DSPy, credits to A.I. Scribe on YouTube

Why DSPy Matters

1. Bridging the Gap: Generally, working with LMs involves intricate prompt engineering — crafting the perfect text prompts to get the desired output. While effective, this approach can be time-consuming and prone to errors. DSPy simplifies this process by offering a potentially better way to guide LM behavior.

2. User-Friendly: DSPy’s core philosophy is to make LM programming accessible to a broader audience. It achieves this by providing a high-level programming interface in Python, a popular language in Machine Learning and Data Science. If you’re already familiar with Python, you can use your knowledge to interact with LMs, eliminating the need to master complex prompt structures.

3. Composability: DSPy’s building blocks are designed to be modular and composable. You can create simple programs for basic tasks and combine them to construct more complex pipelines. This modularity encourages code reuse, experimentation, and easier troubleshooting.

4. Optimization: DSPy includes an automatic compiler that optimizes your programs for the specific LM you’re using. This means you don’t have to worry about the intricacies of different models; DSPy handles the optimization under the hood.

DSPy in Action: A Simple Example

This code is from the official documentation of DSPy (Source: Minimal Working Example | DSPy (dspy-docs.vercel.app))

Let’s walk through a basic example using the DSPy library. We’ll utilize the GSM8K dataset and the OpenAI GPT-3.5-turbo model to simulate prompting tasks within DSPy.

Please execute the following command to install DSPy before you import the module:

!pip install dspy

Let’s import the required modules and set up the language model.

import dspy
from dspy.datasets.gsm8k import GSM8K, gsm8k_metric

# Set up the LM
turbo = dspy.OpenAI(model='gpt-3.5-turbo-instruct', max_tokens=250)
dspy.settings.configure(lm=turbo)

# Load math questions from the GSM8K dataset
gsm8k = GSM8K()
gsm8k_trainset, gsm8k_devset = gsm8k.train[:10], gsm8k.dev[:10]

Let’s review what gsm8k_trainset and gsm8k_devset are:

print(gsm8k_trainset)

Now, with the environment set up, let’s define a custom program that uses the ChainOfThought module to perform step-by-step reasoning in order to generate answers.

class CoT(dspy.Module):
def __init__(self):
super().__init__()
self.prog = dspy.ChainOfThought("question -> answer")

def forward(self, question):
return self.prog(question=question)

Let’s proceed to compile our simple program using the BootstrapFewShot teleprompter.

from dspy.teleprompt import BootstrapFewShot

# Set up the optimizer: we want to "bootstrap" (i.e., self-generate) 4-shot examples of our CoT program.
config = dict(max_bootstrapped_demos=4, max_labeled_demos=4)

# Optimize! Use the `gsm8k_metric` here. In general, the metric is going to tell the optimizer how well it's doing.
teleprompter = BootstrapFewShot(metric=gsm8k_metric, **config)
optimized_cot = teleprompter.compile(CoT(), trainset=gsm8k_trainset)

Now that we have a compiled (optimized) DSPy program let’s evaluate its performance on the dev dataset.

from dspy.evaluate import Evaluate

# Set up the evaluator, which can be used multiple times.
evaluate = Evaluate(devset=gsm8k_devset, metric=gsm8k_metric, num_threads=4, display_progress=True, display_table=0)

# Evaluate our `optimized_cot` program.
evaluate(optimized_cot)

We can gain insight by reviewing the most recent generations and inspecting the model’s history for a deeper understanding of the model’s interactions.

turbo.inspect_history(n=1)

This example demonstrates the process of setting up your environment, defining a custom module, compiling a model, and evaluating its performance using the provided dataset and teleprompter configurations.

To test what you have just built, you can run:

optimized_cot(question='Your Question Here')

The Road Ahead

DSPy is still in its early stages, but it has the potential to revolutionize how we build applications that harness the power of LMs. As the framework evolves, we can expect to see even more innovative use cases and easier integration with various LM providers.

Let’s Get Started!

If you’re intrigued by DSPy, I encourage you to explore the official online documentation and tutorials. The best way to understand anything is to get your hands dirty!

References:

[1] DSPy Documentation | DSPy (dspy-docs.vercel.app)
[2] https://x.com/lateinteraction/status/1694748401374490946
[3] https://github.com/stanfordnlp/dspy

--

--