lium-core 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lium_core/__init__.py +0 -0
- lium_core/shared_config/__init__.py +9 -0
- lium_core/shared_config/client.py +54 -0
- lium_core/shared_config/defaults.py +124 -0
- lium_core/shared_config/model.py +22 -0
- lium_core/shared_config/utils.py +13 -0
- lium_core-0.1.0.dist-info/METADATA +7 -0
- lium_core-0.1.0.dist-info/RECORD +9 -0
- lium_core-0.1.0.dist-info/WHEEL +4 -0
lium_core/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
from lium_core.shared_config.client import SharedConfigClient
|
|
2
|
+
from lium_core.shared_config.defaults import DEFAULT_SHARED_CONFIG
|
|
3
|
+
from lium_core.shared_config.model import SharedConfig
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"SharedConfig",
|
|
7
|
+
"SharedConfigClient",
|
|
8
|
+
"DEFAULT_SHARED_CONFIG",
|
|
9
|
+
]
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import threading
|
|
3
|
+
import time
|
|
4
|
+
|
|
5
|
+
import requests
|
|
6
|
+
|
|
7
|
+
from lium_core.shared_config.defaults import DEFAULT_SHARED_CONFIG
|
|
8
|
+
from lium_core.shared_config.model import SharedConfig
|
|
9
|
+
from lium_core.shared_config.utils import dict_diff
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class SharedConfigClient:
|
|
15
|
+
def __init__(self, api_url: str, refresh_interval: int = 60):
|
|
16
|
+
self._api_url = api_url
|
|
17
|
+
self._refresh_interval = refresh_interval
|
|
18
|
+
self._lock = threading.Lock()
|
|
19
|
+
self._config: SharedConfig = self._fetch() or DEFAULT_SHARED_CONFIG
|
|
20
|
+
self._running = True
|
|
21
|
+
self._thread = threading.Thread(target=self._refresh_loop, daemon=True)
|
|
22
|
+
self._thread.start()
|
|
23
|
+
|
|
24
|
+
def __getattr__(self, name: str):
|
|
25
|
+
"""Delegate attribute access to the underlying frozen SharedConfig."""
|
|
26
|
+
return getattr(self._config, name)
|
|
27
|
+
|
|
28
|
+
def _fetch(self) -> SharedConfig | None:
|
|
29
|
+
"""Fetch config from API, return None on failure."""
|
|
30
|
+
try:
|
|
31
|
+
response = requests.get(self._api_url, timeout=10)
|
|
32
|
+
response.raise_for_status()
|
|
33
|
+
return SharedConfig.model_validate(response.json())
|
|
34
|
+
except Exception:
|
|
35
|
+
logger.warning("Failed to fetch shared config from %s", self._api_url, exc_info=True)
|
|
36
|
+
return None
|
|
37
|
+
|
|
38
|
+
def _refresh_loop(self) -> None:
|
|
39
|
+
"""Background daemon thread: sleep + fetch."""
|
|
40
|
+
logger.info("Started shared config refresh loop")
|
|
41
|
+
while self._running:
|
|
42
|
+
time.sleep(self._refresh_interval)
|
|
43
|
+
new_config = self._fetch()
|
|
44
|
+
with self._lock:
|
|
45
|
+
if new_config and self._config != new_config:
|
|
46
|
+
for change in dict_diff(self._config.model_dump(), new_config.model_dump()):
|
|
47
|
+
logger.info("Config changed %s", change)
|
|
48
|
+
self._config = new_config
|
|
49
|
+
else:
|
|
50
|
+
logger.debug("Shared config unchanged")
|
|
51
|
+
|
|
52
|
+
def stop(self) -> None:
|
|
53
|
+
"""Stop background refresh."""
|
|
54
|
+
self._running = False
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
from lium_core.shared_config.model import SharedConfig
|
|
2
|
+
|
|
3
|
+
DEFAULT_SHARED_CONFIG = SharedConfig(
|
|
4
|
+
machine_prices={
|
|
5
|
+
"NVIDIA B300 SXM6 AC": 3.67,
|
|
6
|
+
"NVIDIA B200": 2.99,
|
|
7
|
+
"NVIDIA H200": 1.90,
|
|
8
|
+
"NVIDIA H200 NVL": 1.67,
|
|
9
|
+
"NVIDIA H100 80GB HBM3": 1.26,
|
|
10
|
+
"NVIDIA H100 NVL": 1.11,
|
|
11
|
+
"NVIDIA H100 PCIe": 1.11,
|
|
12
|
+
"NVIDIA H800 80GB HBM3": 0.88,
|
|
13
|
+
"NVIDIA H800 NVL": 0.80,
|
|
14
|
+
"NVIDIA H800 PCIe": 0.80,
|
|
15
|
+
"NVIDIA GeForce RTX 5090": 0.17,
|
|
16
|
+
"NVIDIA GeForce RTX 4090": 0.14,
|
|
17
|
+
"NVIDIA GeForce RTX 4090 D": 0.11,
|
|
18
|
+
"NVIDIA RTX 4000 Ada Generation": 0.16,
|
|
19
|
+
"NVIDIA RTX 6000 Ada Generation": 0.31,
|
|
20
|
+
"NVIDIA RTX PRO 6000 Blackwell Server Edition": 0.77,
|
|
21
|
+
"NVIDIA RTX PRO 6000 Blackwell Workstation Edition": 0.84,
|
|
22
|
+
"NVIDIA L4": 0.11,
|
|
23
|
+
"NVIDIA L40S": 0.34,
|
|
24
|
+
"NVIDIA L40": 0.29,
|
|
25
|
+
"NVIDIA RTX 2000 Ada Generation": 0.07,
|
|
26
|
+
"NVIDIA A100 80GB PCIe": 0.36,
|
|
27
|
+
"NVIDIA A100-SXM4-80GB": 0.43,
|
|
28
|
+
"NVIDIA RTX A6000": 0.24,
|
|
29
|
+
"NVIDIA RTX A5000": 0.16,
|
|
30
|
+
"NVIDIA RTX A4500": 0.13,
|
|
31
|
+
"NVIDIA RTX A4000": 0.12,
|
|
32
|
+
"NVIDIA A40": 0.12,
|
|
33
|
+
"NVIDIA A30": 0.10,
|
|
34
|
+
"NVIDIA GeForce RTX 3090": 0.13,
|
|
35
|
+
},
|
|
36
|
+
required_deposit_amount={
|
|
37
|
+
"NVIDIA B300 SXM6 AC": 0.274,
|
|
38
|
+
"NVIDIA B200": 0.223,
|
|
39
|
+
"NVIDIA H200": 0.158,
|
|
40
|
+
"NVIDIA H200 NVL": 0.131,
|
|
41
|
+
"NVIDIA H100 80GB HBM3": 0.103,
|
|
42
|
+
"NVIDIA H100 NVL": 0.086,
|
|
43
|
+
"NVIDIA H100 PCIe": 0.086,
|
|
44
|
+
"NVIDIA H800 80GB HBM3": 0.051,
|
|
45
|
+
"NVIDIA H800 NVL": 0.045,
|
|
46
|
+
"NVIDIA H800 PCIe": 0.045,
|
|
47
|
+
"NVIDIA GeForce RTX 5090": 0.014,
|
|
48
|
+
"NVIDIA GeForce RTX 4090": 0.010,
|
|
49
|
+
"NVIDIA GeForce RTX 4090 D": 0.008,
|
|
50
|
+
"NVIDIA RTX PRO 6000 Blackwell Server Edition": 0.0425,
|
|
51
|
+
"NVIDIA RTX PRO 6000 Blackwell Workstation Edition": 0.0459,
|
|
52
|
+
"NVIDIA RTX 6000 Ada Generation": 0.017,
|
|
53
|
+
"NVIDIA L4": 0.008,
|
|
54
|
+
"NVIDIA L40S": 0.027,
|
|
55
|
+
"NVIDIA L40": 0.024,
|
|
56
|
+
"NVIDIA A100 80GB PCIe": 0.027,
|
|
57
|
+
"NVIDIA A100-SXM4-80GB": 0.031,
|
|
58
|
+
"NVIDIA RTX A6000": 0.018,
|
|
59
|
+
"NVIDIA RTX A5000": 0.009,
|
|
60
|
+
"NVIDIA RTX A4500": 0.008,
|
|
61
|
+
"NVIDIA RTX A4000": 0.008,
|
|
62
|
+
"NVIDIA GeForce RTX 3090": 0.008,
|
|
63
|
+
},
|
|
64
|
+
gpu_architectures={
|
|
65
|
+
# Blackwell (sm_100/120)
|
|
66
|
+
"NVIDIA B200": {"arch": "blackwell", "min_cuda": 12.8, "compute_cap": "sm_100"},
|
|
67
|
+
"NVIDIA GeForce RTX 5090": {"arch": "blackwell", "min_cuda": 12.8, "compute_cap": "sm_120"},
|
|
68
|
+
# Hopper (sm_90)
|
|
69
|
+
"NVIDIA H100 80GB HBM3": {"arch": "hopper", "min_cuda": 11.8, "optimal_cuda": 12.2, "compute_cap": "sm_90"},
|
|
70
|
+
"NVIDIA H100 NVL": {"arch": "hopper", "min_cuda": 11.8, "optimal_cuda": 12.2, "compute_cap": "sm_90"},
|
|
71
|
+
"NVIDIA H100 PCIe": {"arch": "hopper", "min_cuda": 11.8, "optimal_cuda": 12.2, "compute_cap": "sm_90"},
|
|
72
|
+
"NVIDIA H200": {"arch": "hopper", "min_cuda": 11.8, "optimal_cuda": 12.2, "compute_cap": "sm_90"},
|
|
73
|
+
"NVIDIA H800 80GB HBM3": {"arch": "hopper", "min_cuda": 11.8, "optimal_cuda": 12.2, "compute_cap": "sm_90"},
|
|
74
|
+
"NVIDIA H800 NVL": {"arch": "hopper", "min_cuda": 11.8, "optimal_cuda": 12.2, "compute_cap": "sm_90"},
|
|
75
|
+
"NVIDIA H800 PCIe": {"arch": "hopper", "min_cuda": 11.8, "optimal_cuda": 12.2, "compute_cap": "sm_90"},
|
|
76
|
+
# Ada Lovelace (sm_89)
|
|
77
|
+
"NVIDIA GeForce RTX 4090": {"arch": "ada", "min_cuda": 11.8, "compute_cap": "sm_89"},
|
|
78
|
+
"NVIDIA GeForce RTX 4090 D": {"arch": "ada", "min_cuda": 11.8, "compute_cap": "sm_89"},
|
|
79
|
+
"NVIDIA L4": {"arch": "ada", "min_cuda": 11.8, "compute_cap": "sm_89"},
|
|
80
|
+
"NVIDIA L40": {"arch": "ada", "min_cuda": 11.8, "compute_cap": "sm_89"},
|
|
81
|
+
"NVIDIA L40S": {"arch": "ada", "min_cuda": 11.8, "compute_cap": "sm_89"},
|
|
82
|
+
"NVIDIA RTX 2000 Ada Generation": {"arch": "ada", "min_cuda": 11.8, "compute_cap": "sm_89"},
|
|
83
|
+
"NVIDIA RTX 4000 Ada Generation": {"arch": "ada", "min_cuda": 11.8, "compute_cap": "sm_89"},
|
|
84
|
+
"NVIDIA RTX 6000 Ada Generation": {"arch": "ada", "min_cuda": 11.8, "compute_cap": "sm_89"},
|
|
85
|
+
# Ampere (sm_86)
|
|
86
|
+
"NVIDIA A100 80GB PCIe": {"arch": "ampere", "min_cuda": 11.0, "compute_cap": "sm_86"},
|
|
87
|
+
"NVIDIA A100-SXM4-80GB": {"arch": "ampere", "min_cuda": 11.0, "compute_cap": "sm_86"},
|
|
88
|
+
"NVIDIA A30": {"arch": "ampere", "min_cuda": 11.0, "compute_cap": "sm_86"},
|
|
89
|
+
"NVIDIA A40": {"arch": "ampere", "min_cuda": 11.0, "compute_cap": "sm_86"},
|
|
90
|
+
"NVIDIA RTX A4000": {"arch": "ampere", "min_cuda": 11.0, "compute_cap": "sm_86"},
|
|
91
|
+
"NVIDIA RTX A4500": {"arch": "ampere", "min_cuda": 11.0, "compute_cap": "sm_86"},
|
|
92
|
+
"NVIDIA RTX A5000": {"arch": "ampere", "min_cuda": 11.0, "compute_cap": "sm_86"},
|
|
93
|
+
"NVIDIA RTX A6000": {"arch": "ampere", "min_cuda": 11.0, "compute_cap": "sm_86"},
|
|
94
|
+
"NVIDIA GeForce RTX 3090": {"arch": "ampere", "min_cuda": 11.0, "compute_cap": "sm_86"},
|
|
95
|
+
},
|
|
96
|
+
driver_cuda_map={
|
|
97
|
+
450: 11.0,
|
|
98
|
+
470: 11.4,
|
|
99
|
+
495: 11.5,
|
|
100
|
+
510: 11.6,
|
|
101
|
+
515: 11.7,
|
|
102
|
+
525: 12.0,
|
|
103
|
+
530: 12.1,
|
|
104
|
+
535: 12.2,
|
|
105
|
+
545: 12.3,
|
|
106
|
+
550: 12.4,
|
|
107
|
+
555: 12.5,
|
|
108
|
+
560: 12.6,
|
|
109
|
+
565: 12.7,
|
|
110
|
+
570: 12.8,
|
|
111
|
+
575: 12.8,
|
|
112
|
+
580: 13.0,
|
|
113
|
+
590: 13.1,
|
|
114
|
+
},
|
|
115
|
+
machine_max_price_rate=3.0,
|
|
116
|
+
machine_min_price_rate=0.5,
|
|
117
|
+
rental_fees_rate=0.9,
|
|
118
|
+
collateral_days=7,
|
|
119
|
+
collateral_contract_address="0x7DCCb5659c70Ce2104A9bb79E9E257473ECbe628",
|
|
120
|
+
bittensor_netuid=51,
|
|
121
|
+
volume_gb_hour_price_usd=0.00005,
|
|
122
|
+
max_initial_port_count=200,
|
|
123
|
+
total_burn_emission=0.91,
|
|
124
|
+
)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from pydantic import BaseModel, ConfigDict
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class SharedConfig(BaseModel):
|
|
5
|
+
model_config = ConfigDict(frozen=True)
|
|
6
|
+
|
|
7
|
+
# Dicts
|
|
8
|
+
machine_prices: dict[str, float]
|
|
9
|
+
required_deposit_amount: dict[str, float]
|
|
10
|
+
gpu_architectures: dict[str, dict]
|
|
11
|
+
driver_cuda_map: dict[int, float]
|
|
12
|
+
|
|
13
|
+
# Scalars
|
|
14
|
+
machine_max_price_rate: float
|
|
15
|
+
machine_min_price_rate: float
|
|
16
|
+
rental_fees_rate: float
|
|
17
|
+
collateral_days: int
|
|
18
|
+
collateral_contract_address: str
|
|
19
|
+
bittensor_netuid: int
|
|
20
|
+
volume_gb_hour_price_usd: float
|
|
21
|
+
max_initial_port_count: int
|
|
22
|
+
total_burn_emission: float
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
def dict_diff(old: dict, new: dict, prefix: str = "") -> list[str]:
|
|
2
|
+
"""Return list of human-readable strings describing differences."""
|
|
3
|
+
changes: list[str] = []
|
|
4
|
+
all_keys = old.keys() | new.keys()
|
|
5
|
+
for key in sorted(all_keys):
|
|
6
|
+
path = f"{prefix}.{key}" if prefix else key
|
|
7
|
+
old_val = old.get(key)
|
|
8
|
+
new_val = new.get(key)
|
|
9
|
+
if isinstance(old_val, dict) and isinstance(new_val, dict):
|
|
10
|
+
changes.extend(dict_diff(old_val, new_val, path))
|
|
11
|
+
elif old_val != new_val:
|
|
12
|
+
changes.append(f"[{path}]: {old_val} -> {new_val}")
|
|
13
|
+
return changes
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
lium_core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
lium_core/shared_config/__init__.py,sha256=FU_Q0XCAPQsjHsIdN9tze6Uc9t9mQrGJ4_vV48VYMV0,274
|
|
3
|
+
lium_core/shared_config/client.py,sha256=M0sGuagg3UWrwt6niyeojVDTVoqcMk-7gFsc0xauPoE,2043
|
|
4
|
+
lium_core/shared_config/defaults.py,sha256=UXsS29LamaWvspc3DEvH67r7TLnPTtKwiMd1wtArzd0,5644
|
|
5
|
+
lium_core/shared_config/model.py,sha256=Yo06ZupnJetR32cLxJ_7zXbT43n0e6KOLXer-bue_v0,590
|
|
6
|
+
lium_core/shared_config/utils.py,sha256=MlBlhfxI9SvngURute5SSusFMS1THDwhvM8GuHZgNzU,600
|
|
7
|
+
lium_core-0.1.0.dist-info/METADATA,sha256=NGW3w1bx_Ws2P4h3h0IvyOpCktjCwOkvEz04oC1n3jk,187
|
|
8
|
+
lium_core-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
9
|
+
lium_core-0.1.0.dist-info/RECORD,,
|