model_factory.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. from typing import Optional
  2. from langchain.callbacks.base import Callbacks
  3. from core.model_providers.error import ProviderTokenNotInitError, LLMBadRequestError
  4. from core.model_providers.model_provider_factory import ModelProviderFactory, DEFAULT_MODELS
  5. from core.model_providers.models.base import BaseProviderModel
  6. from core.model_providers.models.embedding.base import BaseEmbedding
  7. from core.model_providers.models.entity.model_params import ModelKwargs, ModelType
  8. from core.model_providers.models.llm.base import BaseLLM
  9. from core.model_providers.models.speech2text.base import BaseSpeech2Text
  10. from extensions.ext_database import db
  11. from models.provider import TenantDefaultModel
  12. class ModelFactory:
  13. @classmethod
  14. def get_text_generation_model_from_model_config(cls, tenant_id: str,
  15. model_config: dict,
  16. streaming: bool = False,
  17. callbacks: Callbacks = None) -> Optional[BaseLLM]:
  18. provider_name = model_config.get("provider")
  19. model_name = model_config.get("name")
  20. completion_params = model_config.get("completion_params", {})
  21. return cls.get_text_generation_model(
  22. tenant_id=tenant_id,
  23. model_provider_name=provider_name,
  24. model_name=model_name,
  25. model_kwargs=ModelKwargs(
  26. temperature=completion_params.get('temperature', 0),
  27. max_tokens=completion_params.get('max_tokens', 256),
  28. top_p=completion_params.get('top_p', 0),
  29. frequency_penalty=completion_params.get('frequency_penalty', 0.1),
  30. presence_penalty=completion_params.get('presence_penalty', 0.1)
  31. ),
  32. streaming=streaming,
  33. callbacks=callbacks
  34. )
  35. @classmethod
  36. def get_text_generation_model(cls,
  37. tenant_id: str,
  38. model_provider_name: Optional[str] = None,
  39. model_name: Optional[str] = None,
  40. model_kwargs: Optional[ModelKwargs] = None,
  41. streaming: bool = False,
  42. callbacks: Callbacks = None,
  43. deduct_quota: bool = True) -> Optional[BaseLLM]:
  44. """
  45. get text generation model.
  46. :param tenant_id: a string representing the ID of the tenant.
  47. :param model_provider_name:
  48. :param model_name:
  49. :param model_kwargs:
  50. :param streaming:
  51. :param callbacks:
  52. :param deduct_quota:
  53. :return:
  54. """
  55. is_default_model = False
  56. if model_provider_name is None and model_name is None:
  57. default_model = cls.get_default_model(tenant_id, ModelType.TEXT_GENERATION)
  58. if not default_model:
  59. raise LLMBadRequestError(f"Default model is not available. "
  60. f"Please configure a Default System Reasoning Model "
  61. f"in the Settings -> Model Provider.")
  62. model_provider_name = default_model.provider_name
  63. model_name = default_model.model_name
  64. is_default_model = True
  65. # get model provider
  66. model_provider = ModelProviderFactory.get_preferred_model_provider(tenant_id, model_provider_name)
  67. if not model_provider:
  68. raise ProviderTokenNotInitError(f"Model {model_name} provider credentials is not initialized.")
  69. # init text generation model
  70. model_class = model_provider.get_model_class(model_type=ModelType.TEXT_GENERATION)
  71. try:
  72. model_instance = model_class(
  73. model_provider=model_provider,
  74. name=model_name,
  75. model_kwargs=model_kwargs,
  76. streaming=streaming,
  77. callbacks=callbacks
  78. )
  79. except LLMBadRequestError as e:
  80. if is_default_model:
  81. raise LLMBadRequestError(f"Default model {model_name} is not available. "
  82. f"Please check your model provider credentials.")
  83. else:
  84. raise e
  85. if is_default_model or not deduct_quota:
  86. model_instance.deduct_quota = False
  87. return model_instance
  88. @classmethod
  89. def get_embedding_model(cls,
  90. tenant_id: str,
  91. model_provider_name: Optional[str] = None,
  92. model_name: Optional[str] = None) -> Optional[BaseEmbedding]:
  93. """
  94. get embedding model.
  95. :param tenant_id: a string representing the ID of the tenant.
  96. :param model_provider_name:
  97. :param model_name:
  98. :return:
  99. """
  100. if model_provider_name is None and model_name is None:
  101. default_model = cls.get_default_model(tenant_id, ModelType.EMBEDDINGS)
  102. if not default_model:
  103. raise LLMBadRequestError(f"Default model is not available. "
  104. f"Please configure a Default Embedding Model "
  105. f"in the Settings -> Model Provider.")
  106. model_provider_name = default_model.provider_name
  107. model_name = default_model.model_name
  108. # get model provider
  109. model_provider = ModelProviderFactory.get_preferred_model_provider(tenant_id, model_provider_name)
  110. if not model_provider:
  111. raise ProviderTokenNotInitError(f"Model {model_name} provider credentials is not initialized.")
  112. # init embedding model
  113. model_class = model_provider.get_model_class(model_type=ModelType.EMBEDDINGS)
  114. return model_class(
  115. model_provider=model_provider,
  116. name=model_name
  117. )
  118. @classmethod
  119. def get_speech2text_model(cls,
  120. tenant_id: str,
  121. model_provider_name: Optional[str] = None,
  122. model_name: Optional[str] = None) -> Optional[BaseSpeech2Text]:
  123. """
  124. get speech to text model.
  125. :param tenant_id: a string representing the ID of the tenant.
  126. :param model_provider_name:
  127. :param model_name:
  128. :return:
  129. """
  130. if model_provider_name is None and model_name is None:
  131. default_model = cls.get_default_model(tenant_id, ModelType.SPEECH_TO_TEXT)
  132. if not default_model:
  133. raise LLMBadRequestError(f"Default model is not available. "
  134. f"Please configure a Default Speech-to-Text Model "
  135. f"in the Settings -> Model Provider.")
  136. model_provider_name = default_model.provider_name
  137. model_name = default_model.model_name
  138. # get model provider
  139. model_provider = ModelProviderFactory.get_preferred_model_provider(tenant_id, model_provider_name)
  140. if not model_provider:
  141. raise ProviderTokenNotInitError(f"Model {model_name} provider credentials is not initialized.")
  142. # init speech to text model
  143. model_class = model_provider.get_model_class(model_type=ModelType.SPEECH_TO_TEXT)
  144. return model_class(
  145. model_provider=model_provider,
  146. name=model_name
  147. )
  148. @classmethod
  149. def get_moderation_model(cls,
  150. tenant_id: str,
  151. model_provider_name: str,
  152. model_name: str) -> Optional[BaseProviderModel]:
  153. """
  154. get moderation model.
  155. :param tenant_id: a string representing the ID of the tenant.
  156. :param model_provider_name:
  157. :param model_name:
  158. :return:
  159. """
  160. # get model provider
  161. model_provider = ModelProviderFactory.get_preferred_model_provider(tenant_id, model_provider_name)
  162. if not model_provider:
  163. raise ProviderTokenNotInitError(f"Model {model_name} provider credentials is not initialized.")
  164. # init moderation model
  165. model_class = model_provider.get_model_class(model_type=ModelType.MODERATION)
  166. return model_class(
  167. model_provider=model_provider,
  168. name=model_name
  169. )
  170. @classmethod
  171. def get_default_model(cls, tenant_id: str, model_type: ModelType) -> TenantDefaultModel:
  172. """
  173. get default model of model type.
  174. :param tenant_id:
  175. :param model_type:
  176. :return:
  177. """
  178. # get default model
  179. default_model = db.session.query(TenantDefaultModel) \
  180. .filter(
  181. TenantDefaultModel.tenant_id == tenant_id,
  182. TenantDefaultModel.model_type == model_type.value
  183. ).first()
  184. if not default_model:
  185. model_provider_rules = ModelProviderFactory.get_provider_rules()
  186. for model_provider_name, model_provider_rule in model_provider_rules.items():
  187. model_provider = ModelProviderFactory.get_preferred_model_provider(tenant_id, model_provider_name)
  188. if not model_provider:
  189. continue
  190. model_list = model_provider.get_supported_model_list(model_type)
  191. if model_list:
  192. model_info = model_list[0]
  193. default_model = TenantDefaultModel(
  194. tenant_id=tenant_id,
  195. model_type=model_type.value,
  196. provider_name=model_provider_name,
  197. model_name=model_info['id']
  198. )
  199. db.session.add(default_model)
  200. db.session.commit()
  201. break
  202. return default_model
  203. @classmethod
  204. def update_default_model(cls,
  205. tenant_id: str,
  206. model_type: ModelType,
  207. provider_name: str,
  208. model_name: str) -> TenantDefaultModel:
  209. """
  210. update default model of model type.
  211. :param tenant_id:
  212. :param model_type:
  213. :param provider_name:
  214. :param model_name:
  215. :return:
  216. """
  217. model_provider_name = ModelProviderFactory.get_provider_names()
  218. if provider_name not in model_provider_name:
  219. raise ValueError(f'Invalid provider name: {provider_name}')
  220. model_provider = ModelProviderFactory.get_preferred_model_provider(tenant_id, provider_name)
  221. if not model_provider:
  222. raise ProviderTokenNotInitError(f"Model {model_name} provider credentials is not initialized.")
  223. model_list = model_provider.get_supported_model_list(model_type)
  224. model_ids = [model['id'] for model in model_list]
  225. if model_name not in model_ids:
  226. raise ValueError(f'Invalid model name: {model_name}')
  227. # get default model
  228. default_model = db.session.query(TenantDefaultModel) \
  229. .filter(
  230. TenantDefaultModel.tenant_id == tenant_id,
  231. TenantDefaultModel.model_type == model_type.value
  232. ).first()
  233. if default_model:
  234. # update default model
  235. default_model.provider_name = provider_name
  236. default_model.model_name = model_name
  237. db.session.commit()
  238. else:
  239. # create default model
  240. default_model = TenantDefaultModel(
  241. tenant_id=tenant_id,
  242. model_type=model_type.value,
  243. provider_name=provider_name,
  244. model_name=model_name,
  245. )
  246. db.session.add(default_model)
  247. db.session.commit()
  248. return default_model