|
10 | 10 |
|
11 | 11 | import requests |
12 | 12 |
|
13 | | -from gpuhunt._internal.models import AcceleratorVendor, QueryFilter, RawCatalogItem |
| 13 | +from gpuhunt._internal.models import ( |
| 14 | + AcceleratorVendor, |
| 15 | + CPUArchitecture, |
| 16 | + QueryFilter, |
| 17 | + RawCatalogItem, |
| 18 | +) |
14 | 19 | from gpuhunt.providers import AbstractProvider |
15 | 20 |
|
16 | 21 | logger = logging.getLogger(__name__) |
|
26 | 31 | "A100-PCIe-80GB": ("A100", AcceleratorVendor.NVIDIA, 80), |
27 | 32 | "A100-SXM-80GB": ("A100", AcceleratorVendor.NVIDIA, 80), |
28 | 33 | "H100-SXM-80GB": ("H100", AcceleratorVendor.NVIDIA, 80), |
| 34 | + "H200-SXM-141GB": ("H200", AcceleratorVendor.NVIDIA, 141), |
| 35 | + "B200-SXM-180GB": ("B200", AcceleratorVendor.NVIDIA, 180), |
| 36 | + "GB200-NVL-186GB": ("GB200", AcceleratorVendor.NVIDIA, 186), |
29 | 37 | "L40S-48GB": ("L40S", AcceleratorVendor.NVIDIA, 48), |
30 | 38 | "A40-PCIe-48GB": ("A40", AcceleratorVendor.NVIDIA, 48), |
31 | 39 | "MI300X-192GB": ("MI300X", AcceleratorVendor.AMD, 192), |
32 | | - # TODO: The following GPUs are listed on https://crusoe.ai/cloud/pricing but not yet |
33 | | - # returned by the instance types API. Add them once Crusoe exposes them: |
34 | | - # - H200 141GB ($4.29/GPU-hr on-demand, spot: contact sales) |
35 | | - # - GB200 186GB (contact sales) |
36 | | - # - B200 180GB (contact sales) |
37 | | - # - MI355X 288GB ($3.45 listed but not confirmed; also missing from KNOWN_AMD_GPUS) |
| 40 | + "MI355X_288GB": ("MI355X", AcceleratorVendor.AMD, 288), |
38 | 41 | } |
39 | 42 |
|
40 | 43 | # Per-GPU-hour pricing from https://crusoe.ai/cloud/pricing |
|
44 | 47 | "A100-PCIe-80GB": (1.65, 1.20), |
45 | 48 | "A100-SXM-80GB": (1.95, 1.30), |
46 | 49 | "H100-SXM-80GB": (3.90, 1.60), |
| 50 | + "H200-SXM-141GB": (4.29, None), |
| 51 | + # TODO: B200 estimated from B200/H100 ratio on other providers; update once Crusoe publishes rates. |
| 52 | + # GB200 and MI355X pricing not known yet; update once Crusoe publishes rates. |
| 53 | + "B200-SXM-180GB": (7.25, None), |
47 | 54 | "L40S-48GB": (1.00, 0.50), |
48 | 55 | "A40-PCIe-48GB": (0.90, 0.40), |
49 | 56 | "MI300X-192GB": (3.45, 0.95), |
@@ -137,6 +144,13 @@ def _request(self, method: str, path: str, params: Optional[dict] = None) -> req |
137 | 144 | return requests.request(method, url, headers=headers, params=params, timeout=TIMEOUT) |
138 | 145 |
|
139 | 146 |
|
| 147 | +def _get_cpu_arch(spec: dict) -> str: |
| 148 | + cpu_type = spec.get("cpu_type", "") |
| 149 | + if cpu_type == "arm64": |
| 150 | + return CPUArchitecture.ARM.value |
| 151 | + return CPUArchitecture.X86.value |
| 152 | + |
| 153 | + |
140 | 154 | def _get_available_type_locations(capacities: list[dict]) -> dict[str, list[str]]: |
141 | 155 | best_qty: dict[tuple[str, str], int] = defaultdict(int) |
142 | 156 | for cap in capacities: |
@@ -191,6 +205,7 @@ def _make_gpu_items( |
191 | 205 | gpu_memory=gpu_memory, |
192 | 206 | spot=None, |
193 | 207 | disk_size=float(spec["disk_gb"]) if spec.get("disk_gb") else None, |
| 208 | + cpu_arch=_get_cpu_arch(spec), |
194 | 209 | # disk_gb: ephemeral NVMe size in GB (0 = no ephemeral disk). |
195 | 210 | # Used by dstack to decide whether to create a persistent data disk. |
196 | 211 | provider_data={"disk_gb": spec.get("disk_gb", 0)}, |
@@ -231,6 +246,7 @@ def _make_cpu_items(product_name: str, spec: dict, locations: list[str]) -> list |
231 | 246 | gpu_memory=None, |
232 | 247 | spot=False, |
233 | 248 | disk_size=float(spec["disk_gb"]) if spec.get("disk_gb") else None, |
| 249 | + cpu_arch=_get_cpu_arch(spec), |
234 | 250 | provider_data={"disk_gb": spec.get("disk_gb", 0)}, |
235 | 251 | ) |
236 | 252 |
|
|
0 commit comments