pre_serve.rs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. //! Types for the `before_serve` configuration and `exec_aliases` table.
  2. //!
  3. //! Lives outside `config.rs` so the latter stays under the 500-line limit
  4. //! the project enforces (see AGENTS.md).
  5. use serde::Deserialize;
  6. /// Behaviour on a non-zero exit code for a [`PreServeCommand`].
  7. #[derive(Clone, Copy, Debug, PartialEq, Eq, Default, Deserialize)]
  8. #[serde(rename_all = "lowercase")]
  9. pub enum OnFailure {
  10. #[default]
  11. Abort,
  12. Warn,
  13. Continue,
  14. }
  15. /// One entry in a `before_serve` block.
  16. #[derive(Clone, Debug, Deserialize)]
  17. #[serde(untagged)]
  18. pub enum PreServeCommand {
  19. Bare(String),
  20. Configured {
  21. command: String,
  22. #[serde(default)]
  23. on_failure: OnFailure,
  24. },
  25. }
  26. impl PreServeCommand {
  27. pub fn command(&self) -> &str {
  28. match self {
  29. PreServeCommand::Bare(c) => c,
  30. PreServeCommand::Configured { command, .. } => command,
  31. }
  32. }
  33. pub fn on_failure(&self) -> OnFailure {
  34. match self {
  35. PreServeCommand::Bare(_) => OnFailure::default(),
  36. PreServeCommand::Configured { on_failure, .. } => *on_failure,
  37. }
  38. }
  39. }
  40. #[derive(Clone, Debug, Default, Deserialize)]
  41. pub struct BeforeServeTable {
  42. #[serde(default)]
  43. pub commands: Vec<PreServeCommand>,
  44. }
  45. #[derive(Clone, Debug, Default, Deserialize)]
  46. pub struct ModsTable {
  47. #[serde(default)]
  48. pub commands: Vec<PreServeCommand>,
  49. }
  50. /// Distributed execution backend — `mp` or `ray`. Absent means single-node.
  51. #[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize)]
  52. #[serde(rename_all = "lowercase")]
  53. pub enum DistributedBackend {
  54. Mp,
  55. Ray,
  56. }
  57. /// Recipe arguments — either an inline TOML string (split by whitespace) or
  58. /// a `Vec<String>` list. Accepted in TOML as either:
  59. ///
  60. /// ```toml
  61. /// args = """
  62. /// --gpu-memory-utilization 0.90
  63. /// --max-model-len 262144
  64. /// """
  65. /// ```
  66. ///
  67. /// ```toml
  68. /// args = ["--gpu-memory-utilization", "0.90"]
  69. /// ```
  70. #[derive(Clone, Debug, Deserialize)]
  71. #[serde(untagged)]
  72. pub enum RecipeArgs {
  73. List(Vec<String>),
  74. Inline(String),
  75. }
  76. impl Default for RecipeArgs {
  77. fn default() -> Self {
  78. RecipeArgs::List(Vec::new())
  79. }
  80. }
  81. impl RecipeArgs {
  82. pub fn to_vec(&self) -> Vec<String> {
  83. match self {
  84. RecipeArgs::Inline(s) => s.split_whitespace().map(String::from).collect(),
  85. RecipeArgs::List(v) => v.clone(),
  86. }
  87. }
  88. /// Replace all occurrences of `placeholder` with `replacement` in each
  89. /// arg string. Used to substitute model path references (e.g.
  90. /// `{{mtp_draft}}`) with resolved HF cache paths per-node.
  91. pub fn substitute(&self, placeholder: &str, replacement: &str) -> RecipeArgs {
  92. match self {
  93. RecipeArgs::Inline(s) => RecipeArgs::Inline(s.replace(placeholder, replacement)),
  94. RecipeArgs::List(v) => RecipeArgs::List(
  95. v.iter()
  96. .map(|a| a.replace(placeholder, replacement))
  97. .collect(),
  98. ),
  99. }
  100. }
  101. }
  102. impl std::fmt::Display for DistributedBackend {
  103. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  104. match self {
  105. DistributedBackend::Mp => write!(f, "mp"),
  106. DistributedBackend::Ray => write!(f, "ray"),
  107. }
  108. }
  109. }