qwen.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. import os
  2. from http import HTTPStatus
  3. import dashscope
  4. from openai import OpenAI
  5. from dashscope import Generation
  6. import copy
  7. from qwen_agent.llm.base import LLMBase
  8. class Qwen(LLMBase):
  9. def __init__(self, model='qwen', api_key='', model_server=''):
  10. super().__init__(model=model, api_key=api_key)
  11. self.model_server = model_server
  12. self.source = ''
  13. self.gen = None
  14. self._client = OpenAI(
  15. api_key="none", base_url=model_server
  16. )
  17. if self.model_server.startswith('http'):
  18. # openai.api_base = self.model_server
  19. # openai.api_key = 'none'
  20. self.source = 'local'
  21. elif self.model_server.startswith('dashscope'):
  22. dashscope.api_key = self.api_key or os.getenv('DASHSCOPE_API_KEY', default='')
  23. if not dashscope.api_key:
  24. print('There is no DASHSCOPE_API_KEY!')
  25. self.source = 'dashscope'
  26. def chat(self, query=None, stream=False, messages=None, stop=None):
  27. if self.source == 'dashscope':
  28. if dashscope.api_key: # use dashscope interface
  29. print('Now using dashscope api')
  30. self.gen = Generation()
  31. return self._chat_dashscope(query, stream=stream, messages=messages, stop=stop)
  32. else:
  33. print('There is no DASHSCOPE_API_KEY!')
  34. return 'Failed! There is no DASHSCOPE_API_KEY!'
  35. else: # use locally deployed qwen
  36. print('Now using locally deployed qwen')
  37. return super().chat(query, stream=stream, messages=messages, stop=stop)
  38. def _chat_stream(self, query, messages=None, stop=None):
  39. print(f'begin: stream in qwen')
  40. if messages:
  41. response = self._client.chat.completions.create(
  42. model=self.model, messages=messages, stop=stop, stream=True)
  43. else:
  44. response = self._client.chat.completions.create(
  45. model=self.model,
  46. messages=[{
  47. 'role': 'user',
  48. 'content': query
  49. }],
  50. stop=stop,
  51. stream=True
  52. )
  53. for chunk in response:
  54. if hasattr(chunk.choices[0].delta, 'content') and chunk.choices[0].delta.content:
  55. print(chunk.choices[0].delta.content, end='', flush=True)
  56. yield chunk.choices[0].delta.content
  57. def _chat_no_stream(self, query, messages=None, stop=None):
  58. print('begin: no stream in qwen')
  59. if messages:
  60. if query:
  61. local_message = copy.deepcopy(messages)
  62. local_message.append({'role': 'user','content': query})
  63. _messages = local_message
  64. else:
  65. _messages = messages
  66. response = self._client.chat.completions.create(model=self.model,
  67. messages=_messages,
  68. stop=stop,
  69. stream=False)
  70. else:
  71. response = self._client.chat.completions.create(model=self.model,
  72. messages=[{
  73. 'role': 'user',
  74. 'content': query
  75. }],
  76. stop=stop,
  77. stream=False)
  78. print(response.choices[0].message.content)
  79. return response.choices[0].message.content
  80. def _chat_dashscope(self, query, stream=False, messages=None, stop=None):
  81. if stream:
  82. return self._chat_dashscope_stream(query, messages, stop=stop)
  83. else:
  84. return self._chat_dashscope_no_stream(query, messages, stop=stop)
  85. def _chat_dashscope_stream(self, query, messages=None, stop=None):
  86. # print(query)
  87. if not stop:
  88. stop = []
  89. if messages:
  90. response = self.gen.call(
  91. self.model,
  92. messages=messages,
  93. result_format='message', # set the result to be "message" format.
  94. stop_words=[{'stop_str': word, 'mode': 'exclude'} for word in stop],
  95. stream=True,
  96. top_p=0.8
  97. )
  98. else:
  99. response = self.gen.call(
  100. self.model,
  101. messages=[{
  102. 'role': 'user',
  103. 'content': query
  104. }],
  105. result_format='message', # set the result to be "message" format.
  106. stop_words=[{'stop_str': word, 'mode': 'exclude'} for word in stop],
  107. stream=True,
  108. top_p=0.8
  109. )
  110. last_len = 0
  111. delay_len = 5
  112. in_delay = 0
  113. text = ''
  114. for trunk in response:
  115. if trunk.status_code == HTTPStatus.OK:
  116. # print(trunk)
  117. text = trunk.output.choices[0].message.content
  118. if (len(text)-last_len) <= delay_len: # less than delay_len
  119. in_delay = 1
  120. continue
  121. else:
  122. in_delay = 0 # print
  123. real_text = text[:-delay_len] # delay print
  124. now_rsp = real_text[last_len:]
  125. yield now_rsp
  126. last_len = len(real_text)
  127. else:
  128. err = 'Error code: %s, error message: %s' % (
  129. trunk.code, trunk.message
  130. )
  131. if trunk.code == 'DataInspectionFailed':
  132. err += '\n'
  133. err += '错误码: 数据检查失败,错误信息: 输入数据可能包含不适当的内容。'
  134. print(err)
  135. text = ''
  136. yield f'{err}'
  137. if text and (in_delay == 1 or last_len != len(text)):
  138. yield text[last_len:]
  139. def _chat_dashscope_no_stream(self, query, messages=None, stop=None):
  140. print('begin: no stream in dashscope')
  141. if not stop:
  142. stop = []
  143. if messages:
  144. response = self.gen.call(
  145. self.model,
  146. messages=messages,
  147. result_format='message', # set the result to be "message" format.
  148. stream=False,
  149. stop_words=[{'stop_str': word, 'mode': 'exclude'} for word in stop],
  150. top_p=0.8
  151. )
  152. else:
  153. response = self.gen.call(
  154. self.model,
  155. messages=[{
  156. 'role': 'user',
  157. 'content': query
  158. }],
  159. result_format='message', # set the result to be "message" format.
  160. stream=False,
  161. stop_words=[{'stop_str': word, 'mode': 'exclude'} for word in stop],
  162. top_p=0.8
  163. )
  164. # print(response)
  165. if response.status_code == HTTPStatus.OK:
  166. return response.output.choices[0].message.content
  167. else:
  168. err = 'Error code: %s, error message: %s' % (
  169. response.code, response.message
  170. )
  171. return err
  172. def qwen_chat_func(self, messages, functions=None):
  173. print('begin: no stream in qwen_chat_func')
  174. if not functions:
  175. functions = []
  176. if functions:
  177. response = self._client.chat.completions.create(
  178. model=self.model, messages=messages, functions=functions
  179. )
  180. else:
  181. response = self._client.chat.completions.create(model=self.model, messages=messages)
  182. return response.choices[0].message