score_chain.py 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. from dataclasses import dataclass
  2. from typing import List, Optional
  3. from gpustack.policies.base import (
  4. ModelInstance,
  5. ModelInstanceScore,
  6. ModelInstanceScorer,
  7. ModelInstanceScheduleCandidate,
  8. ScheduleCandidatesScorer,
  9. )
  10. @dataclass
  11. class CandidateScoreChain:
  12. scorers: List[ScheduleCandidatesScorer]
  13. async def score(
  14. self, candidates: List[ModelInstanceScheduleCandidate]
  15. ) -> List[ModelInstanceScheduleCandidate]:
  16. if not candidates:
  17. return candidates
  18. total_scores = {id(candidate): 0.0 for candidate in candidates}
  19. for scorer in self.scorers:
  20. # Reset candidate scores so each scorer computes its own score.
  21. for candidate in candidates:
  22. candidate.score = None
  23. scored = await scorer.score(candidates)
  24. for candidate in scored:
  25. total_scores[id(candidate)] += candidate.score or 0
  26. for candidate in candidates:
  27. candidate.score = total_scores[id(candidate)]
  28. return candidates
  29. class ModelInstanceScoreChain:
  30. def __init__(
  31. self,
  32. scorers: List[ModelInstanceScorer],
  33. total_max_score: Optional[float] = None,
  34. ):
  35. self._scorers = [s for s in scorers if s.max_score and s.max_score > 0]
  36. self._total_max_score = total_max_score
  37. self._sum_max_score = sum(s.max_score for s in self._scorers)
  38. if self._total_max_score is None or self._sum_max_score == 0:
  39. self._scale_factor = 1.0
  40. else:
  41. self._scale_factor = self._total_max_score / self._sum_max_score
  42. async def score(self, instances: List[ModelInstance]) -> List[ModelInstanceScore]:
  43. if not instances:
  44. return []
  45. if not self._scorers:
  46. return [
  47. ModelInstanceScore(model_instance=instance, score=0)
  48. for instance in instances
  49. ]
  50. if self._sum_max_score == 0:
  51. return [
  52. ModelInstanceScore(model_instance=instance, score=0)
  53. for instance in instances
  54. ]
  55. score_sum = {id(instance): 0.0 for instance in instances}
  56. instance_map = {id(instance): instance for instance in instances}
  57. for scorer in self._scorers:
  58. scores = await scorer.score_instances(instances)
  59. for item in scores:
  60. key = id(item.model_instance)
  61. if key in score_sum:
  62. score_sum[key] += item.score or 0
  63. results = []
  64. for key, instance in instance_map.items():
  65. score = score_sum[key] * self._scale_factor
  66. results.append(ModelInstanceScore(model_instance=instance, score=score))
  67. return results