llm_instant_model.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. package models
  2. import (
  3. "context"
  4. "database/sql"
  5. "fmt"
  6. "time"
  7. "yunion.io/x/log"
  8. "yunion.io/x/pkg/errors"
  9. "yunion.io/x/sqlchemy"
  10. api "yunion.io/x/onecloud/pkg/apis/llm"
  11. "yunion.io/x/onecloud/pkg/cloudcommon/db"
  12. )
  13. var llmInstantModelManager *SLLMInstantModelManager
  14. func init() {
  15. GetLLMInstantModelManager()
  16. }
  17. func GetLLMInstantModelManager() *SLLMInstantModelManager {
  18. if llmInstantModelManager == nil {
  19. llmInstantModelManager = &SLLMInstantModelManager{
  20. SResourceBaseManager: db.NewResourceBaseManager(
  21. SLLMInstantModel{},
  22. "llm_instant_models_tbl",
  23. "llm_with_instant_model",
  24. "llm_with_instant_models",
  25. ),
  26. }
  27. llmInstantModelManager.SetVirtualObject(llmInstantModelManager)
  28. }
  29. return llmInstantModelManager
  30. }
  31. type SLLMInstantModelManager struct {
  32. db.SResourceBaseManager
  33. db.SStatusResourceBaseManager
  34. }
  35. type SLLMInstantModel struct {
  36. db.SResourceBase
  37. db.SStatusResourceBase
  38. LlmId string `width:"128" charset:"ascii" nullable:"false" list:"user" primary:"true"`
  39. // InstantModelId instant model 主键 id(SInstantModel.Id)
  40. InstantModelId string `name:"model_id" width:"128" charset:"ascii" nullable:"false" list:"user" primary:"true"`
  41. // Model Tag
  42. Tag string `width:"64" charset:"utf8" nullable:"true" list:"user"`
  43. // Model Name
  44. ModelName string `width:"128" charset:"utf8" nullable:"false" list:"user"`
  45. IsProbed bool `list:"user"`
  46. IsMounted bool `list:"user"`
  47. // IsSystem tristate.TriState `list:"user"`
  48. }
  49. func (man *SLLMInstantModelManager) fetchLLMInstantModel(llmId string, instantModelId string) (*SLLMInstantModel, error) {
  50. q := man.RawQuery().Equals("llm_id", llmId).Equals("model_id", instantModelId)
  51. llmInstantModel := SLLMInstantModel{}
  52. err := q.First(&llmInstantModel)
  53. if err != nil {
  54. if errors.Cause(err) == sql.ErrNoRows {
  55. return nil, errors.ErrNotFound
  56. }
  57. return nil, errors.Wrap(err, "Query")
  58. }
  59. llmInstantModel.SetModelManager(man, &llmInstantModel)
  60. return &llmInstantModel, nil
  61. }
  62. func (man *SLLMInstantModelManager) getDeletedModelIds(llmId string) ([]string, error) {
  63. q := man.RawQuery("model_id").Equals("llm_id", llmId).IsTrue("deleted").Distinct()
  64. llmInstantModel := make([]SLLMInstantModel, 0)
  65. err := db.FetchModelObjects(man, q, &llmInstantModel)
  66. if err != nil {
  67. return nil, errors.Wrap(err, "Query")
  68. }
  69. instantModelIds := make([]string, len(llmInstantModel))
  70. for i := range llmInstantModel {
  71. instantModelIds[i] = llmInstantModel[i].InstantModelId
  72. }
  73. return instantModelIds, nil
  74. }
  75. func (man *SLLMInstantModelManager) updateInstantModel(ctx context.Context, llmId string, instantModelId string, mdlName string, tag string, probed, mounted *bool) (*SLLMInstantModel, error) {
  76. mdl, err := man.fetchLLMInstantModel(llmId, instantModelId)
  77. if err != nil && errors.Cause(err) != errors.ErrNotFound {
  78. return nil, errors.Wrap(err, "updateInstantModel")
  79. }
  80. mountStr := "nil"
  81. probedStr := "nil"
  82. if mounted != nil {
  83. mountStr = fmt.Sprintf("%v", *mounted)
  84. }
  85. if probed != nil {
  86. probedStr = fmt.Sprintf("%v", *probed)
  87. }
  88. log.Debugf("=======updateInstantModel %#v to mounted %s, probed %s", mdl, mountStr, probedStr)
  89. if mdl == nil {
  90. // if no such app
  91. mdl = &SLLMInstantModel{
  92. LlmId: llmId,
  93. InstantModelId: instantModelId,
  94. ModelName: mdlName,
  95. // IsSystem: tristate.None,
  96. // Entry: entry,
  97. }
  98. // if isSys != nil {
  99. // if *isSys {
  100. // mdl.IsSystem = tristate.True
  101. // } else {
  102. // mdl.IsSystem = tristate.False
  103. // }
  104. // }
  105. mdl.Tag = tag
  106. if probed != nil {
  107. mdl.IsProbed = *probed
  108. }
  109. if mounted != nil {
  110. mdl.IsMounted = *mounted
  111. }
  112. mdl.syncStatus()
  113. err := man.TableSpec().Insert(ctx, mdl)
  114. if err != nil {
  115. return nil, errors.Wrap(err, "Insert")
  116. }
  117. return mdl, nil
  118. } else {
  119. _, err := db.Update(mdl, func() error {
  120. if len(tag) > 0 {
  121. mdl.Tag = tag
  122. }
  123. if len(mdlName) > 0 {
  124. mdl.ModelName = mdlName
  125. }
  126. // if isSys != nil {
  127. // if *isSys {
  128. // mdl.IsSystem = tristate.True
  129. // } else {
  130. // mdl.IsSystem = tristate.False
  131. // }
  132. // }
  133. // if len(entry) > 0 {
  134. // app.Entry = entry
  135. // }
  136. if probed != nil {
  137. mdl.IsProbed = *probed
  138. if mdl.IsProbed {
  139. mdl.Status = api.LLM_STATUS_READY
  140. } else {
  141. mdl.Status = api.LLM_STATUS_DELETED
  142. }
  143. }
  144. if mounted != nil {
  145. mdl.IsMounted = *mounted
  146. }
  147. mdl.syncStatus()
  148. return nil
  149. })
  150. if err != nil {
  151. return nil, errors.Wrap(err, "Update")
  152. }
  153. }
  154. return mdl, nil
  155. }
  156. func (man *SLLMInstantModelManager) filterModels(q *sqlchemy.SQuery, isProbed, isMounted, isSystem *bool) *sqlchemy.SQuery {
  157. if isProbed != nil {
  158. if *isProbed {
  159. q = q.IsTrue("is_probed")
  160. } else {
  161. q = q.IsFalse("is_probed")
  162. }
  163. }
  164. if isMounted != nil {
  165. if *isMounted {
  166. q = q.IsTrue("is_mounted")
  167. } else {
  168. q = q.IsFalse("is_mounted")
  169. }
  170. }
  171. if isSystem != nil {
  172. if *isSystem {
  173. q = q.IsTrue("is_system")
  174. } else {
  175. q = q.Filter(sqlchemy.OR(
  176. sqlchemy.IsNull(q.Field("is_system")),
  177. sqlchemy.IsFalse(q.Field("is_system")),
  178. ))
  179. }
  180. }
  181. return q
  182. }
  183. func (mdl *SLLMInstantModel) FindInstantModel(isInstall bool) (*SInstantModel, error) {
  184. instMdl, err := GetInstantModelManager().GetInstantModelById(mdl.InstantModelId)
  185. if err != nil {
  186. return nil, errors.Wrap(err, "FindInstantModel")
  187. }
  188. return instMdl, nil
  189. }
  190. func (mdl *SLLMInstantModel) syncStatus() {
  191. if !mdl.IsProbed && !mdl.IsMounted {
  192. mdl.MarkDelete()
  193. } else {
  194. mdl.Deleted = false
  195. mdl.DeletedAt = time.Time{}
  196. }
  197. }
  198. func (mdl *SLLMInstantModel) getMountPaths(isInstall bool) ([]api.LLMMountDirInfo, error) {
  199. info, err := mdl.getMountPathsFromImage(isInstall)
  200. if err != nil {
  201. return nil, errors.Wrap(err, "getMountPathsFromImage")
  202. }
  203. return info, nil
  204. }
  205. func (mdl *SLLMInstantModel) getMountPathsFromImage(isInstall bool) ([]api.LLMMountDirInfo, error) {
  206. instMdl, err := mdl.FindInstantModel(isInstall)
  207. if err != nil {
  208. return nil, errors.Wrap(err, "findInstantApp")
  209. }
  210. if instMdl == nil {
  211. return nil, nil
  212. }
  213. info := make([]api.LLMMountDirInfo, 0)
  214. info = append(info, api.LLMMountDirInfo{
  215. ImageId: instMdl.ImageId,
  216. })
  217. return info, nil
  218. }
  219. func (man *SLLMInstantModelManager) DeleteByLlmId(ctx context.Context, llmId string) error {
  220. q := man.Query().Equals("llm_id", llmId)
  221. models := make([]SLLMInstantModel, 0)
  222. err := db.FetchModelObjects(man, q, &models)
  223. if err != nil {
  224. return errors.Wrap(err, "FetchModelObjects")
  225. }
  226. for i := range models {
  227. _, err := db.Update(&models[i], func() error {
  228. return models[i].MarkDelete()
  229. })
  230. if err != nil {
  231. return errors.Wrapf(err, "delete llm model %s", models[i].ModelName)
  232. }
  233. }
  234. return nil
  235. }
  236. func (man *SLLMInstantModelManager) purgeModelList(llmId string) error {
  237. err := man.TableSpec().GetTableSpec().DeleteFrom(map[string]interface{}{
  238. "llm_id": llmId,
  239. })
  240. if err != nil {
  241. return errors.Wrap(err, "purgeModelList.DeleteFrom")
  242. }
  243. return nil
  244. }
  245. func (mdl *SLLMInstantModel) purgeModelList() error {
  246. return GetLLMInstantModelManager().purgeModelList(mdl.InstantModelId)
  247. }