77import signal
88from lightllm .server .core .objs .out_token_circlequeue import LIGHTLLM_OUT_TOKEN_QUEUE_SIZE , LIGHTLLM_TOKEN_MAX_BYTES
99from lightllm .server .core .objs .req import ChunkedPrefillReq , TokenHealingReq
10+ from lightllm .server .multimodal_params import ImageItem
1011from lightllm .server .tokenizer import get_tokenizer
11- from lightllm .utils .config_utils import get_config_json
12+ from lightllm .utils .config_utils import get_hidden_size
1213from lightllm .utils .log_utils import init_logger
1314from transformers import AutoTokenizer
1415
1516logger = init_logger (__name__ )
1617
1718
18- def get_shm_size_gb ():
19+ def check_recommended_shm_size (args ):
20+ shm_size , recommended_shm_size , is_shm_sufficient = _check_shm_size (args )
21+ if not args .disable_shm_warning and not is_shm_sufficient :
22+ _start_shm_size_warning_thread (shm_size , recommended_shm_size )
23+ else :
24+ logger .info (
25+ f"SHM check: Available={ shm_size :.2f} GB,"
26+ f"Recommended={ recommended_shm_size :.2f} GB."
27+ f"Sufficient: { is_shm_sufficient } " ,
28+ )
29+
30+
31+ def _check_shm_size (args ):
32+ RED = "\033 [91m"
33+ ENDC = "\033 [0m"
34+ shm_size = _get_system_shm_size_gb ()
35+ required_size = _get_recommended_shm_size_gb (args ) # 128G
36+ if shm_size < required_size :
37+ logger .warning (f"{ RED } Available shm size is less than 128G: { shm_size :.2f} G{ ENDC } " )
38+ return shm_size , required_size , False
39+ else : # shm_size >= required_size
40+ return shm_size , required_size , True
41+
42+
43+ def _start_shm_size_warning_thread (shm_size , required_shm_size ):
44+ shm_warning_thread = threading .Thread (
45+ target = _periodic_shm_warning ,
46+ args = (
47+ shm_size ,
48+ required_shm_size ,
49+ ),
50+ daemon = True ,
51+ )
52+ shm_warning_thread .start ()
53+
54+
55+ def _get_system_shm_size_gb ():
1956 """
20- 获取 /dev/shm 的总大小( 以GB为单位) 。
57+ 获取 /dev/shm 的总大小( 以GB为单位) 。
2158 """
2259 try :
2360 shm_path = "/dev/shm"
@@ -34,87 +71,70 @@ def get_shm_size_gb():
3471 return 0
3572
3673
37- def get_required_shm_size_gb (args , max_image_resolution = (3940 , 2160 ), dtype_size = 2 ):
74+ def _get_recommended_shm_size_gb (args , max_image_resolution = (3940 , 2160 ), dtype_size = 2 ):
3875 """
39- 获取所需的 /dev/shm 大小( 以GB为单位) 。
76+ 获取所需的 /dev/shm 大小( 以GB为单位) 。
4077 """
41- model_config = get_config_json (args .model_dir )
4278 tokenizer = get_tokenizer (args .model_dir , trust_remote_code = True )
4379
80+ # 估算input_token和logprob占用shm大小,由于是double和int64,所以固定占用8个字节
81+ input_token_logprob_size_bytes = args .running_max_req_size * 8 * 2 * args .max_req_total_len
82+
83+ # 估算Req所需的shm大小
84+ if args .token_healing_mode :
85+ req_class_size = ctypes .sizeof (TokenHealingReq )
86+ else :
87+ req_class_size = ctypes .sizeof (ChunkedPrefillReq )
88+ req_shm_size_bytes = req_class_size * args .running_max_req_size
89+
4490 if not args .enable_multimodal :
45- # by default, 非多模态 24 GB
46- total_required_size_gb = 24
91+ total_recommended_shm_size_gb = (req_shm_size_bytes + input_token_logprob_size_bytes ) / (1024 ** 3 ) + 2
4792 else :
93+ # 存储图片数据所需的shm大小
4894 num_channels = 3
4995 image_width , image_height = max_image_resolution
5096 image_size_bytes = image_width * image_height * num_channels
5197
5298 # 假设加载最大分辨率图片时,通过 tokenizer 得到最多的 image_tokens
5399 if not hasattr (tokenizer , "get_image_token_length" ):
54100 raise AttributeError ("Tokenizer must have a 'get_image_token_length' method for multimodal models." )
55- max_image_tokens = tokenizer .get_image_token_length (None )
101+ fake_image_item = ImageItem (
102+ type = "image_size" ,
103+ data = max_image_resolution ,
104+ )
105+ fake_image_item .image_w = fake_image_item ._data [0 ]
106+ fake_image_item .image_h = fake_image_item ._data [1 ]
107+ max_image_tokens = tokenizer .get_image_token_length (fake_image_item )
56108
57109 # 估算图片 token 所需的资源
58- hidden_size = model_config . get ( "hidden_size" )
110+ hidden_size = get_hidden_size ( args . model_dir )
59111 if hidden_size is None :
60- logger .warning ("Model config not contain 'hidden_size', using 4096 by default." )
112+ logger .warning (
113+ "Model config not contain 'hidden_size', " "using 4096 by default to calculate recommended shm size."
114+ )
61115 image_token_size_bytes = max_image_tokens * 4096 * dtype_size
62116 else :
63117 image_token_size_bytes = max_image_tokens * hidden_size * dtype_size
64118
65- # 估算Req所需的shm大小
66- if args .token_healing_mode :
67- req_class_size = ctypes .sizeof (TokenHealingReq )
68- else :
69- req_class_size = ctypes .sizeof (ChunkedPrefillReq )
70- req_shm_size_bytes = req_class_size * args .running_max_req_size
71-
72- # 估算OutTokenQueue所需shm大小
73- out_token_queue_size_bytes = LIGHTLLM_TOKEN_MAX_BYTES * LIGHTLLM_OUT_TOKEN_QUEUE_SIZE
74-
75- total_required_size = (
119+ total_recommended_shm_size_gb = (
76120 args .cache_capacity * (image_size_bytes + image_token_size_bytes )
77121 + req_shm_size_bytes
78- + out_token_queue_size_bytes
122+ + input_token_logprob_size_bytes
79123 )
80124
81- total_required_size_gb = total_required_size / (1024 ** 3 ) + 2
82-
83- return total_required_size_gb
125+ total_recommended_shm_size_gb = total_recommended_shm_size_gb / (1024 ** 3 ) + 2
84126
85-
86- def check_shm_size (args ):
87- RED = "\033 [91m"
88- ENDC = "\033 [0m"
89- shm_size = get_shm_size_gb ()
90- required_size = get_required_shm_size_gb (args ) # 128G
91- if shm_size < required_size :
92- logger .warning (f"{ RED } Available shm size is less than 128G: { shm_size :.2f} G{ ENDC } " )
93- return shm_size , required_size , False
94- else : # shm_size >= required_size
95- return shm_size , required_size , True
127+ return total_recommended_shm_size_gb
96128
97129
98- def periodic_shm_warning (shm_size , required_shm_size ):
130+ def _periodic_shm_warning (shm_size , required_shm_size ):
99131 RED = "\033 [91m"
100132 ENDC = "\033 [0m"
101133 while True :
102134 logger .warning (
103- f"{ RED } Insufficient shared memory (SHM) available." ,
104- f"Required: { required_shm_size :.2f} G, Available: { shm_size :.2f} G.\n " ,
105- "If running in Docker, you can increase SHM size with the `--shm-size` flag, " ,
135+ f"{ RED } Insufficient shared memory (SHM) available."
136+ f"Required: { required_shm_size :.2f} G, Available: { shm_size :.2f} G.\n "
137+ "If running in Docker, you can increase SHM size with the `--shm-size` flag, "
106138 f"like so: `docker run --shm-size=30g [your_image]`{ ENDC } " ,
107139 )
108140 time .sleep (120 ) # 每 120 秒打印一次警告日志
109-
110-
111- def start_shm_size_warning_thread (shm_size , required_shm_size ):
112- shm_warning_thread = threading .Thread (
113- target = periodic_shm_warning ,
114- args = (
115- shm_size ,
116- required_shm_size ,
117- ),
118- daemon = True ,
119- )
120- shm_warning_thread .start ()
0 commit comments