Skip to content

Commit 0a6b50e

Browse files
Improve error message on invalid lm setup (#8378)
1 parent aa0a2fc commit 0a6b50e

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

dspy/predict/predict.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,22 @@ def _forward_preprocess(self, **kwargs):
9999

100100
# Get the right LM to use.
101101
lm = kwargs.pop("lm", self.lm) or settings.lm
102-
assert isinstance(lm, BaseLM), "No LM is loaded."
102+
103+
if lm is None:
104+
raise ValueError(
105+
"No LM is loaded. Please configure the LM using `dspy.configure(lm=dspy.LM(...))`. e.g, "
106+
"`dspy.configure(lm=dspy.LM('openai/gpt-4o-mini'))`"
107+
)
108+
109+
if isinstance(lm, str):
110+
# Many users mistakenly use `dspy.configure(lm="openai/gpt-4o-mini")` instead of
111+
# `dspy.configure(lm=dspy.LM("openai/gpt-4o-mini"))`, so we are providing a specific error message.
112+
raise ValueError(
113+
f"LM must be an instance of `dspy.BaseLM`, not a string. Instead of using a string like "
114+
f"'dspy.configure(lm=\"{lm}\")', please configure the LM like 'dspy.configure(lm=dspy.LM(\"{lm}\"))'"
115+
)
116+
elif not isinstance(lm, BaseLM):
117+
raise ValueError(f"LM must be an instance of `dspy.BaseLM`, not {type(lm)}. Received `lm={lm}`.")
103118

104119
# If temperature is unset or <=0.15, and n > 1, set temperature to 0.7 to keep randomness.
105120
temperature = config.get("temperature") or lm.kwargs.get("temperature")

tests/predict/test_predict.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,28 @@ def test_positional_arguments():
582582
)
583583

584584

585+
def test_error_message_on_invalid_lm_setup():
586+
# No LM is loaded.
587+
with pytest.raises(ValueError, match="No LM is loaded"):
588+
Predict("question -> answer")(question="Why did a chicken cross the kitchen?")
589+
590+
# LM is a string.
591+
dspy.configure(lm="openai/gpt-4o-mini")
592+
with pytest.raises(ValueError) as e:
593+
Predict("question -> answer")(question="Why did a chicken cross the kitchen?")
594+
595+
assert "LM must be an instance of `dspy.BaseLM`, not a string." in str(e.value)
596+
597+
def dummy_lm():
598+
pass
599+
600+
# LM is not an instance of dspy.BaseLM.
601+
dspy.configure(lm=dummy_lm)
602+
with pytest.raises(ValueError) as e:
603+
Predict("question -> answer")(question="Why did a chicken cross the kitchen?")
604+
assert "LM must be an instance of `dspy.BaseLM`, not <class 'function'>." in str(e.value)
605+
606+
585607
@pytest.mark.parametrize("adapter_type", ["chat", "json"])
586608
def test_field_constraints(adapter_type):
587609
class SpyLM(dspy.LM):

0 commit comments

Comments
 (0)