deepseek-ai / DeepSeek-V2

DeepSeek-V2: A Strong, Economical, and Efficient Mixture-of-Experts Language Model
MIT License
3.3k stars 124 forks source link

怎么用dspy里的方法来调用deepseek? #71

Open buchikeke opened 1 month ago

buchikeke commented 1 month ago

我最近有一项dspy的prompt实验,想对比一下不同llm的效果,我不知道该如何接入deepseek,使用官方的OpenAI方法会报错:

deepseek = dspy.OpenAI(api_base ='https://api.deepseek.com/v1', 
             api_key='*********',
             model='deepseek-chat',
             model_type = "chat",
             )

gpt4 = dspy.OpenAI(api_base ='https://openkey.cloud/v1', 
             api_key='**********',
             model='gpt-4o',
             max_tokens = 4096,
             model_type = "chat",
             )

上面gpt4方法可以正常调用,deepseek会报下面这个错误: NotFoundError: Error code: 404 - {'error': {'message': 'Invalid URL (POST /v1chat/completions)', 'type': 'invalid_request_error', 'param': '', 'code': ''}} 具体错误为:

Cell In[21], line 1
----> 1 deepseek("日经跌了1000点,分析一下原因并给出相关依据")

File ~/anaconda3/envs/llms_py310/lib/python3.10/site-packages/dsp/modules/gpt3.py:178, in GPT3.__call__(self, prompt, only_completed, return_sorted, **kwargs)
    170 assert return_sorted is False, "for now"
    172 # if kwargs.get("n", 1) > 1:
    173 #     if self.model_type == "chat":
    174 #         kwargs = {**kwargs}
    175 #     else:
    176 #         kwargs = {**kwargs, "logprobs": 5}
--> 178 response = self.request(prompt, **kwargs)
    180 self.log_usage(response)
    181 choices = response["choices"]

File ~/anaconda3/envs/llms_py310/lib/python3.10/site-packages/backoff/_sync.py:105, in retry_exception.<locals>.retry(*args, **kwargs)
     96 details = {
     97     "target": target,
     98     "args": args,
   (...)
    101     "elapsed": elapsed,
    102 }
    104 try:
--> 105     ret = target(*args, **kwargs)
    106 except exception as e:
    107     max_tries_exceeded = (tries == max_tries_value)

File ~/anaconda3/envs/llms_py310/lib/python3.10/site-packages/dsp/modules/gpt3.py:144, in GPT3.request(self, prompt, **kwargs)
    141 if "model_type" in kwargs:
    142     del kwargs["model_type"]
--> 144 return self.basic_request(prompt, **kwargs)

File ~/anaconda3/envs/llms_py310/lib/python3.10/site-packages/dsp/modules/gpt3.py:117, in GPT3.basic_request(self, prompt, **kwargs)
    115     kwargs["messages"] = messages
    116     kwargs = {"stringify_request": json.dumps(kwargs)}
--> 117     response = chat_request(**kwargs)
    119 else:
    120     kwargs["prompt"] = prompt

File ~/anaconda3/envs/llms_py310/lib/python3.10/site-packages/dsp/modules/gpt3.py:269, in chat_request(**kwargs)
    266 if OPENAI_LEGACY:
    267     return _cached_gpt3_turbo_request_v2_wrapped(**kwargs)
--> 269 return v1_cached_gpt3_turbo_request_v2_wrapped(**kwargs).model_dump()

File ~/anaconda3/envs/llms_py310/lib/python3.10/site-packages/dsp/modules/cache_utils.py:16, in noop_decorator.<locals>.decorator.<locals>.wrapper(*args, **kwargs)
     14 @wraps(func)
     15 def wrapper(*args, **kwargs):
---> 16     return func(*args, **kwargs)

File ~/anaconda3/envs/llms_py310/lib/python3.10/site-packages/dsp/modules/gpt3.py:262, in v1_cached_gpt3_turbo_request_v2_wrapped(**kwargs)
    259 @functools.lru_cache(maxsize=None if cache_turn_on else 0)
    260 @NotebookCacheMemory.cache
    261 def v1_cached_gpt3_turbo_request_v2_wrapped(**kwargs):
--> 262     return v1_cached_gpt3_turbo_request_v2(**kwargs)

File ~/anaconda3/envs/llms_py310/lib/python3.10/site-packages/joblib/memory.py:655, in MemorizedFunc.__call__(self, *args, **kwargs)
    654 def __call__(self, *args, **kwargs):
--> 655     return self._cached_call(args, kwargs)[0]

File ~/anaconda3/envs/llms_py310/lib/python3.10/site-packages/joblib/memory.py:598, in MemorizedFunc._cached_call(self, args, kwargs, shelving)
    595     must_call = True
    597 if must_call:
--> 598     out, metadata = self.call(*args, **kwargs)
    599     if self.mmap_mode is not None:
    600         # Memmap the output at the first call to be consistent with
    601         # later calls
    602         if self._verbose:

File ~/anaconda3/envs/llms_py310/lib/python3.10/site-packages/joblib/memory.py:856, in MemorizedFunc.call(self, *args, **kwargs)
    854 if self._verbose > 0:
    855     print(format_call(self.func, args, kwargs))
--> 856 output = self.func(*args, **kwargs)
    857 self.store_backend.dump_item(
    858     [func_id, args_id], output, verbose=self._verbose)
    860 duration = time.time() - start_time

File ~/anaconda3/envs/llms_py310/lib/python3.10/site-packages/dsp/modules/gpt3.py:256, in v1_cached_gpt3_turbo_request_v2(**kwargs)
    254 if "stringify_request" in kwargs:
    255     kwargs = json.loads(kwargs["stringify_request"])
--> 256 return openai.chat.completions.create(**kwargs)

File ~/anaconda3/envs/llms_py310/lib/python3.10/site-packages/openai/_utils/_utils.py:277, in required_args.<locals>.inner.<locals>.wrapper(*args, **kwargs)
    275             msg = f"Missing required argument: {quote(missing[0])}"
    276     raise TypeError(msg)
--> 277 return func(*args, **kwargs)

File ~/anaconda3/envs/llms_py310/lib/python3.10/site-packages/openai/resources/chat/completions.py:643, in Completions.create(self, messages, model, frequency_penalty, function_call, functions, logit_bias, logprobs, max_tokens, n, parallel_tool_calls, presence_penalty, response_format, seed, service_tier, stop, stream, stream_options, temperature, tool_choice, tools, top_logprobs, top_p, user, extra_headers, extra_query, extra_body, timeout)
    609 @required_args(["messages", "model"], ["messages", "model", "stream"])
    610 def create(
    611     self,
   (...)
    641     timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
    642 ) -> ChatCompletion | Stream[ChatCompletionChunk]:
--> 643     return self._post(
    644         "/chat/completions",
    645         body=maybe_transform(
    646             {
    647                 "messages": messages,
    648                 "model": model,
    649                 "frequency_penalty": frequency_penalty,
    650                 "function_call": function_call,
    651                 "functions": functions,
    652                 "logit_bias": logit_bias,
    653                 "logprobs": logprobs,
    654                 "max_tokens": max_tokens,
    655                 "n": n,
    656                 "parallel_tool_calls": parallel_tool_calls,
    657                 "presence_penalty": presence_penalty,
    658                 "response_format": response_format,
    659                 "seed": seed,
    660                 "service_tier": service_tier,
    661                 "stop": stop,
    662                 "stream": stream,
    663                 "stream_options": stream_options,
    664                 "temperature": temperature,
    665                 "tool_choice": tool_choice,
    666                 "tools": tools,
    667                 "top_logprobs": top_logprobs,
    668                 "top_p": top_p,
    669                 "user": user,
    670             },
    671             completion_create_params.CompletionCreateParams,
    672         ),
    673         options=make_request_options(
    674             extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
    675         ),
    676         cast_to=ChatCompletion,
    677         stream=stream or False,
    678         stream_cls=Stream[ChatCompletionChunk],
    679     )

File ~/anaconda3/envs/llms_py310/lib/python3.10/site-packages/openai/_base_client.py:1266, in SyncAPIClient.post(self, path, cast_to, body, options, files, stream, stream_cls)
   1252 def post(
   1253     self,
   1254     path: str,
   (...)
   1261     stream_cls: type[_StreamT] | None = None,
   1262 ) -> ResponseT | _StreamT:
   1263     opts = FinalRequestOptions.construct(
   1264         method="post", url=path, json_data=body, files=to_httpx_files(files), **options
   1265     )
-> 1266     return cast(ResponseT, self.request(cast_to, opts, stream=stream, stream_cls=stream_cls))

File ~/anaconda3/envs/llms_py310/lib/python3.10/site-packages/openai/_base_client.py:942, in SyncAPIClient.request(self, cast_to, options, remaining_retries, stream, stream_cls)
    933 def request(
    934     self,
    935     cast_to: Type[ResponseT],
   (...)
    940     stream_cls: type[_StreamT] | None = None,
    941 ) -> ResponseT | _StreamT:
--> 942     return self._request(
    943         cast_to=cast_to,
    944         options=options,
    945         stream=stream,
    946         stream_cls=stream_cls,
    947         remaining_retries=remaining_retries,
    948     )

File ~/anaconda3/envs/llms_py310/lib/python3.10/site-packages/openai/_base_client.py:1046, in SyncAPIClient._request(self, cast_to, options, remaining_retries, stream, stream_cls)
   1043         err.response.read()
   1045     log.debug("Re-raising status error")
-> 1046     raise self._make_status_error_from_response(err.response) from None
   1048 return self._process_response(
   1049     cast_to=cast_to,
   1050     options=options,
   (...)
   1053     stream_cls=stream_cls,
   1054 )

请问该怎么解决这个问题?

Lekssays commented 1 month ago

I made a custom model for DeepSeek:

import requests

from dsp import LM

class DeepSeek(LM):
    def __init__(self, model, api_key, **kwargs,):
        self.model = model
        self.api_key = api_key
        self.provider = "default"
        self.history = []
        self.kwargs = {
            "temperature": kwargs.get("temperature", 0.0),
            "max_tokens": min(kwargs.get("max_tokens", 4096), 4096),
            "top_p": kwargs.get("top_p", 0.95),
            "top_k": kwargs.get("top_k", 1),
            "n": kwargs.pop("n", kwargs.pop("num_generations", 1)),
            **kwargs,
        }
        self.kwargs["model"] = model
        self.base_url = "https://api.deepseek.com/chat/completions"

    def basic_request(self, prompt: str, **kwargs):
        headers = {
            "Authorization": "Bearer " + self.api_key,
            "Accept": "application/json",
            "Content-Type": "application/json"
        }

        data = {
            **kwargs,
            "model": self.model,
            "messages": [
                {"role": "user", "content": prompt}
            ],
            "steam": False
        }

        response = requests.post(self.base_url, headers=headers, json=data)
        response = response.json()

        self.history.append({
            "prompt": prompt,
            "response": response,
            "kwargs": kwargs,
        })
        return response

    def __call__(self, prompt, **kwargs):
        response = self.request(prompt, **kwargs)
        completions = [result['message']['content'] for result in response["choices"]]
        return completions

Then I could run it by importing the class:

import dspy
import os

from DeepSeek import DeepSeek

lm = DeepSeek(model='deepseek-coder', api_key=os.getenv("DEEPSEEK_PALTFORM_API_KEY"))
dspy.configure(lm=lm)
qa = dspy.ChainOfThought('question -> answer')
response = qa(question="What is the capital of Paris?")
print(response.answer)
buchikeke commented 1 month ago
"Accept": "application/json",

Thank you ,it works well