Coverage for /opt/cloud/slavespace/usr1/096471637100f3de0fcfc01072822a80/dttest/api/python/llm_datadist_v1/configs.py: 90%

256 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-07-27 10:03 +0800

1#!/usr/bin/env python3 

2# -*- coding: utf-8 -*- 

3# ----------------------------------------------------------------------------------------------------------- 

4# Copyright (c) 2025 Huawei Technologies Co., Ltd. 

5# This program is free software, you can redistribute it and/or modify it under the terms and conditions of 

6# CANN Open Software License Agreement Version 2.0 (the "License"). 

7# Please refer to the License for details. You may not use this file except in compliance with the License. 

8# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, 

9# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. 

10# See LICENSE in the root of the software repository for the full text of the License. 

11# ----------------------------------------------------------------------------------------------------------- 

12 

13import json 

14import socket 

15from enum import IntEnum 

16from typing import List, Tuple, Union 

17 

18from .status import raise_if_false 

19from .utils.utils import ( 

20 check_dict, 

21 check_int32, 

22 check_isinstance, 

23 check_type, 

24 check_uint16, 

25 check_uint32, 

26 check_uint64, 

27) 

28 

29_INVALID_ID = 2**64 - 1 

30 

31 

32class LLMRole(IntEnum): 

33 PROMPT = 1 

34 DECODER = 2 

35 MIX = 3 

36 

37 

38def trans_str_ip(ip): 

39 if check_type(ip, str): 

40 try: 

41 ip_bytes = socket.inet_aton(ip) 

42 return int.from_bytes(ip_bytes, byteorder="little") 

43 except Exception: 

44 raise RuntimeError(f"Can not parse ip str:{ip}") 

45 return ip 

46 

47 

48class LLMClusterInfo(object): 

49 def __init__(self): 

50 self._remote_cluster_id = None 

51 self._remote_role_type = None 

52 self._local_ip_info_list: List[Tuple[int, int]] = [] 

53 self._remote_ip_info_list: List[Tuple[int, int]] = [] 

54 

55 def _check_inputs(self, ip, port): 

56 check_isinstance("ip", ip, [str, int]) 

57 check_uint16("port", port) 

58 return trans_str_ip(ip) 

59 

60 @property 

61 def remote_role_type(self): 

62 return self._remote_role_type 

63 

64 @property 

65 def remote_cluster_id(self): 

66 return self._remote_cluster_id 

67 

68 @property 

69 def local_ip_info_list(self): 

70 return self._local_ip_info_list 

71 

72 @property 

73 def remote_ip_info_list(self): 

74 return self._remote_ip_info_list 

75 

76 @remote_role_type.setter 

77 def remote_role_type(self, remote_role_type: Union[LLMRole, int]): 

78 check_isinstance("remote_role_type", remote_role_type, [LLMRole, int]) 

79 self._remote_role_type = remote_role_type 

80 

81 @remote_cluster_id.setter 

82 def remote_cluster_id(self, remote_cluster_id): 

83 check_uint64("remote_cluster_id", remote_cluster_id) 

84 self._remote_cluster_id = remote_cluster_id 

85 

86 def append_local_ip_info(self, ip: Union[str, int], port: int): 

87 """ 

88 添加本地IP信息 

89 Args: 

90 ip: IP 

91 port: 端口 

92 """ 

93 ip = self._check_inputs(ip, port) 

94 self._local_ip_info_list.append((ip, port)) 

95 

96 def append_remote_ip_info(self, ip: Union[str, int], port: int): 

97 """ 

98 添加对端IP信息 

99 Args: 

100 ip: IP 

101 port: 端口 

102 """ 

103 ip = self._check_inputs(ip, port) 

104 self._remote_ip_info_list.append((ip, port)) 

105 

106 

107class LlmConfig(object): 

108 def __init__(self): 

109 self._options = {} 

110 self._listen_ip_info = "" 

111 self._device_id = None 

112 self._sync_kv_timeout = None 

113 self._deploy_res_path = "" 

114 self._ge_options = {} 

115 self._enable_switch_role = False 

116 

117 # below is offline 

118 self._cluster_info = "" 

119 self._output_max_size = "" 

120 self._mem_utilization = 0.95 

121 self._buf_pool_cfg = "" 

122 self._mem_pool_cfg = "" 

123 self._host_mem_pool_cfg = "" 

124 self._enable_cache_manager = None 

125 self._enable_remote_cache_accessible = None 

126 self._rdma_traffic_class = None 

127 self._rdma_service_level = None 

128 self._local_comm_res = None 

129 

130 def generate_options(self): 

131 """ 

132 生成LLM Engine配置项 

133 Returns: 

134 配置项dict 

135 """ 

136 return self.gen_options() 

137 

138 def gen_options(self): 

139 if self.ge_options: 

140 self._options.update(self.ge_options) 

141 if self.listen_ip_info: 

142 self._options["llm.listenIpInfo"] = str(self.listen_ip_info) 

143 if self.device_id is not None: 

144 if check_type(self.device_id, int): 

145 self._options["ge.exec.deviceId"] = str(self.device_id) 

146 self._options["ge.session_device_id"] = str(self.device_id) 

147 else: 

148 self._options["ge.session_device_id"] = str(self.device_id[0]) 

149 self._options["ge.exec.deviceId"] = ";".join([str(dev) for dev in self.device_id]) 

150 if self.sync_kv_timeout is not None: 

151 self._options["llm.SyncKvCacheWaitTime"] = str(self.sync_kv_timeout) 

152 if self.deploy_res_path: 

153 self._options["llm.deployResPath"] = str(self.deploy_res_path) 

154 if self.buf_pool_cfg: 

155 self._options["llm.BufPoolCfg"] = str(self.buf_pool_cfg) 

156 if self._mem_pool_cfg: 

157 self._options["llm.MemPoolConfig"] = str(self._mem_pool_cfg) 

158 if self._host_mem_pool_cfg: 

159 self._options["llm.HostMemPoolConfig"] = str(self._host_mem_pool_cfg) 

160 if self._enable_cache_manager is not None: 

161 self._options["llm.EnableCacheManager"] = "1" if self._enable_cache_manager else "0" 

162 if self._enable_remote_cache_accessible is not None: 

163 self._options["llm.EnableRemoteCacheAccessible"] = "1" if self._enable_remote_cache_accessible else "0" 

164 

165 # below is offline 

166 if self._cluster_info: 

167 self._options["llm.ClusterInfo"] = str(self.cluster_info) 

168 if self._output_max_size: 

169 self._options["llm.OutputMaxSize"] = str(self.output_max_size) 

170 if self._enable_switch_role: 

171 self._options["llm.EnableSwitchRole"] = "1" 

172 if self._mem_utilization is not None: 

173 self._options["llm.MemoryUtilization"] = str(self.mem_utilization) 

174 if self.rdma_traffic_class is not None: 

175 self._options["llm.RdmaTrafficClass"] = str(self.rdma_traffic_class) 

176 if self.rdma_service_level is not None: 

177 self._options["llm.RdmaServiceLevel"] = str(self.rdma_service_level) 

178 if self._local_comm_res is not None: 

179 self._options["llm.LocalCommRes"] = str(self.local_comm_res) 

180 return self.options 

181 

182 @property 

183 def ge_options(self): 

184 return self._ge_options 

185 

186 @ge_options.setter 

187 def ge_options(self, ge_options): 

188 check_isinstance("ge_options", ge_options, dict) 

189 check_dict("ge_options", ge_options, str, str) 

190 self._ge_options = ge_options 

191 

192 @property 

193 def device_id(self): 

194 return self._device_id 

195 

196 @device_id.setter 

197 def device_id(self, device_id): 

198 check_isinstance("device_id", device_id, [list, tuple, int]) 

199 if check_type(device_id, list) or check_type(device_id, tuple): 

200 check_isinstance("device_id", device_id, [list, tuple], int) 

201 [raise_if_false(dev_id >= 0, "device_id should be greater than or equal to zero.") for dev_id in device_id] 

202 [check_int32("device_id", dev_id) for dev_id in device_id] 

203 else: 

204 check_isinstance("device_id", device_id, int) 

205 raise_if_false(device_id >= 0, "device_id should be greater than or equal to zero.") 

206 check_int32("device_id", device_id) 

207 self._device_id = device_id 

208 

209 @property 

210 def listen_ip_info(self): 

211 return self._listen_ip_info 

212 

213 @listen_ip_info.setter 

214 def listen_ip_info(self, listen_ip_info): 

215 check_isinstance("listen_ip_info", listen_ip_info, str) 

216 self._listen_ip_info = listen_ip_info 

217 

218 @property 

219 def deploy_res_path(self): 

220 return self._deploy_res_path 

221 

222 @deploy_res_path.setter 

223 def deploy_res_path(self, deploy_res_path): 

224 check_isinstance("deploy_res_path", deploy_res_path, str) 

225 self._deploy_res_path = deploy_res_path 

226 

227 @property 

228 def buf_pool_cfg(self): 

229 return self._buf_pool_cfg 

230 

231 @buf_pool_cfg.setter 

232 def buf_pool_cfg(self, buf_pool_cfg): 

233 check_isinstance("buf_pool_cfg", buf_pool_cfg, str) 

234 self._buf_pool_cfg = buf_pool_cfg 

235 

236 @property 

237 def output_max_size(self): 

238 return self._output_max_size 

239 

240 @output_max_size.setter 

241 def output_max_size(self, output_max_size): 

242 check_isinstance("output_max_size", output_max_size, int) 

243 self._output_max_size = output_max_size 

244 

245 @property 

246 def mem_utilization(self): 

247 return self._mem_utilization 

248 

249 @mem_utilization.setter 

250 def mem_utilization(self, mem_utilization): 

251 check_isinstance("mem_utilization", mem_utilization, float) 

252 raise_if_false( 

253 ((mem_utilization >= 0.0) and (mem_utilization <= 1.0)), 

254 f"mem_utilization must be in range [0,1], current:{mem_utilization}", 

255 ) 

256 self._mem_utilization = mem_utilization 

257 

258 @property 

259 def options(self): 

260 return self._options 

261 

262 @property 

263 def cluster_info(self): 

264 return self._cluster_info 

265 

266 @property 

267 def sync_kv_timeout(self): 

268 return self._sync_kv_timeout 

269 

270 @cluster_info.setter 

271 def cluster_info(self, cluster_info): 

272 check_isinstance("cluster_info", cluster_info, str) 

273 cluster_info_dict = json.loads(cluster_info) 

274 if "listen_ip_info" in cluster_info_dict: 

275 for ip_info in cluster_info_dict["listen_ip_info"]: 

276 ip_info["ip"] = trans_str_ip(ip_info["ip"]) 

277 self._cluster_info = json.dumps(cluster_info_dict) 

278 

279 @sync_kv_timeout.setter 

280 def sync_kv_timeout(self, sync_kv_timeout): 

281 check_isinstance("sync_kv_timeout", sync_kv_timeout, [int, str]) 

282 if check_type(sync_kv_timeout, str): 

283 raise_if_false(sync_kv_timeout.isdigit(), "sync_kv_timeout must be digit.") 

284 raise_if_false(int(sync_kv_timeout) > 0, "sync_kv_timeout should be greater than zero.") 

285 check_int32("sync_kv_timeout", int(sync_kv_timeout)) 

286 self._sync_kv_timeout = sync_kv_timeout 

287 

288 @property 

289 def enable_switch_role(self): 

290 return self._enable_switch_role 

291 

292 @enable_switch_role.setter 

293 def enable_switch_role(self, enable_switch_role: bool): 

294 check_isinstance("enable_switch_role", enable_switch_role, [bool]) 

295 self._enable_switch_role = enable_switch_role 

296 

297 @property 

298 def enable_cache_manager(self): 

299 return False if self._enable_cache_manager is None else self._enable_cache_manager 

300 

301 @enable_cache_manager.setter 

302 def enable_cache_manager(self, enable_cache_manager: bool): 

303 check_isinstance("enable_cache_manager", enable_cache_manager, [bool]) 

304 self._enable_cache_manager = enable_cache_manager 

305 

306 @property 

307 def enable_remote_cache_accessible(self): 

308 return False if self._enable_remote_cache_accessible is None else self._enable_remote_cache_accessible 

309 

310 @enable_remote_cache_accessible.setter 

311 def enable_remote_cache_accessible(self, enable_remote_cache_accessible: bool): 

312 check_isinstance("enable_remote_cache_accessible", enable_remote_cache_accessible, [bool]) 

313 self._enable_remote_cache_accessible = enable_remote_cache_accessible 

314 

315 @property 

316 def mem_pool_cfg(self) -> str: 

317 return self._mem_pool_cfg 

318 

319 @mem_pool_cfg.setter 

320 def mem_pool_cfg(self, mem_pool_cfg: str): 

321 check_isinstance("mem_pool_cfg", mem_pool_cfg, str) 

322 self._mem_pool_cfg = mem_pool_cfg 

323 

324 @property 

325 def host_mem_pool_cfg(self) -> str: 

326 return self._host_mem_pool_cfg 

327 

328 @host_mem_pool_cfg.setter 

329 def host_mem_pool_cfg(self, host_mem_pool_cfg: str): 

330 check_isinstance("host_mem_pool_cfg", host_mem_pool_cfg, str) 

331 self._host_mem_pool_cfg = host_mem_pool_cfg 

332 

333 @property 

334 def rdma_traffic_class(self) -> str: 

335 return self._rdma_traffic_class 

336 

337 @rdma_traffic_class.setter 

338 def rdma_traffic_class(self, rdma_traffic_class: int): 

339 check_uint32("rdma_traffic_class", rdma_traffic_class) 

340 self._rdma_traffic_class = rdma_traffic_class 

341 

342 @property 

343 def rdma_service_level(self) -> str: 

344 return self._rdma_service_level 

345 

346 @rdma_service_level.setter 

347 def rdma_service_level(self, rdma_service_level: int): 

348 check_uint32("rdma_service_level", rdma_service_level) 

349 self._rdma_service_level = rdma_service_level 

350 

351 @property 

352 def local_comm_res(self): 

353 return "" if self._local_comm_res is None else self._local_comm_res 

354 

355 @local_comm_res.setter 

356 def local_comm_res(self, local_comm_res): 

357 check_isinstance("local_comm_res", local_comm_res, str) 

358 self._local_comm_res = local_comm_res