llm-benchmark 0.3.27__py2.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.
File without changes
@@ -0,0 +1,51 @@
1
+ import argparse
2
+ import yaml
3
+ import subprocess
4
+ import ollama
5
+
6
+ parser = argparse.ArgumentParser(
7
+ prog="python3 check_models.py",
8
+ description="Before running check_models.py, please make sure you installed ollama successfully \
9
+ on macOS, Linux, or WSL2 on Windows. You can check the website: https://ollama.ai",
10
+ epilog="Author: Jason Chuang")
11
+
12
+ parser.add_argument("-v",
13
+ "--verbose",
14
+ action="store_true",
15
+ help="this program helps you check whether you have ollama benchmark models installed")
16
+
17
+ parser.add_argument("-m",
18
+ "--models",
19
+ type=str,
20
+ help="provide benchmark models YAML file path. ex. ../data/benchmark_models.yml")
21
+
22
+ def parse_yaml(yaml_file_path):
23
+ with open(yaml_file_path, 'r') as stream:
24
+ try:
25
+ data=yaml.safe_load(stream)
26
+ #print(d)
27
+ except yaml.YAMLError as e:
28
+ print(e)
29
+ return data
30
+
31
+ def pull_models(models_file_path):
32
+ print(f"LLM models file path:{models_file_path}")
33
+ print(f"Checking and pulling the following LLM models")
34
+ models_dict = parse_yaml(models_file_path)
35
+ for x in models_dict['models']:
36
+ model_name = x['model']
37
+ print(model_name)
38
+ ollama.pull(model_name)
39
+
40
+ if __name__ == "__main__":
41
+ args = parser.parse_args()
42
+ #print(f"args.verbose value:{args.verbose}")
43
+ if (args.models is not None):
44
+ print(f"args.models file path:{args.models}")
45
+ models_dict = parse_yaml(args.models)
46
+ for x in models_dict['models']:
47
+ model_name = x['model']
48
+ print(model_name)
49
+ result = subprocess.run(['ollama', 'pull', model_name], stdout=subprocess.PIPE)
50
+ result.stdout
51
+
@@ -0,0 +1,22 @@
1
+ import subprocess
2
+
3
+ def run_command(command):
4
+ try:
5
+ result = subprocess.run(command, capture_output=True, text=True, check=True)
6
+ return result.stdout.strip() # Return the output of the command
7
+ except subprocess.CalledProcessError as e:
8
+ print(f"Error executing command '{command}': {e}")
9
+ return None
10
+
11
+ def check_ollama_version(ollamabin='ollama'):
12
+ res = run_command([ollamabin, '--version'])
13
+ ans = res.split('\n')
14
+ #print(ans[-1])
15
+ if("warning" in ans[-1].lower()):
16
+ return ans[-1][27:]
17
+ else:
18
+ return ans[-1][18:]
19
+
20
+ if __name__ == "__main__":
21
+ check_ollama_version()
22
+ check_ollama_version('ollama')
@@ -0,0 +1,57 @@
1
+ # Author: Jason Chuang
2
+ # License: MIT
3
+ version: 1.0
4
+ modeltypes:
5
+ - type: chat
6
+ prompts:
7
+ - prompt: What are your thoughts on the latest scientific discovery regarding black holes?
8
+ keywords: science, recent
9
+ - type: completion
10
+ prompts:
11
+ - prompt: In a world where time travel is possible, a scientist invents a device that allows people to visit any historical event. One day, a young woman decides to travel back in time to...
12
+ keywords:
13
+ - type: instruct
14
+ models:
15
+ - model: mistral:7b
16
+ - model: llama3:8b
17
+ - model: llama3.1:8b
18
+ - model: phi4:14b
19
+ - model: qwen:1.8b
20
+ - model: qwen2:7b
21
+ - model: phi:2.7b
22
+ prompts:
23
+ - prompt: Write a step-by-step guide on how to bake a chocolate cake from scratch.
24
+ keywords: cooking, recipe
25
+ - prompt: Develop a python function that solves the following problem, sudoku game
26
+ keywords: python, sudoku
27
+ - prompt: Create a dialogue between two characters that discusses economic crisis
28
+ keywords: dialogue
29
+ - prompt: In a forest, there are brave lions living there. Please continue the story.
30
+ keywords: sentence completition
31
+ - prompt: I'd like to book a flight for 4 to Seattle in U.S.
32
+ keywords: flight booking
33
+ - type: question-answer
34
+ reference_url: https://www.turing.com/interview-questions/artificial-intelligence
35
+ models:
36
+ - model: gemma:2b
37
+ - model: gemma:7b
38
+ - model: gemma2:9b
39
+ prompts:
40
+ - prompt: Explain Artificial Intelligence and give its applications.
41
+ keywords:
42
+ - prompt: How are machine learning and AI related?
43
+ keywords:
44
+ - prompt: What is Deep Learning based on?
45
+ keywords:
46
+ - prompt: What is the full form of LSTM?
47
+ keywords:
48
+ - prompt: What are different components of GAN?
49
+ keywords:
50
+ - type: vision-image
51
+ reference_url: https://chuangtc.com/Research/llm-vlm.php
52
+ models:
53
+ - model: llava:7b
54
+ - model: llava:13b
55
+ prompts:
56
+ - prompt: Describe the image,
57
+ keywords: sample1.jpg,sample2.jpg,sample3.jpg,sample4.jpg,sample5.jpg
@@ -0,0 +1,11 @@
1
+ # Author: Jason Chuang
2
+ # License: MIT
3
+ version: 1.0
4
+ models:
5
+ - model: phi4:14b
6
+ - model: qwen2:7b
7
+ - model: gemma2:9b
8
+ - model: mistral:7b
9
+ - model: llama3.1:8b
10
+ - model: llava:7b
11
+ - model: llava:13b
@@ -0,0 +1,6 @@
1
+ # Author: Jason Chuang
2
+ # License: MIT
3
+ version: 1.0
4
+ models:
5
+ - model: qwen2:1.5b
6
+ - model: gemma:2b
@@ -0,0 +1,7 @@
1
+ # Author: Jason Chuang
2
+ # License: MIT
3
+ version: 1.0
4
+ models:
5
+ - model: qwen2:1.5b
6
+ - model: gemma:2b
7
+ - model: phi:2.7b
@@ -0,0 +1,8 @@
1
+ # Author: Jason Chuang
2
+ # License: MIT
3
+ version: 1.0
4
+ models:
5
+ - model: qwen2:1.5b
6
+ - model: gemma:2b
7
+ - model: phi:2.7b
8
+ - model: phi3:3.8b
@@ -0,0 +1,10 @@
1
+ # Author: Jason Chuang
2
+ # License: MIT
3
+ version: 1.0
4
+ models:
5
+ - model: phi3:3.8b
6
+ - model: qwen2:7b
7
+ - model: gemma2:9b
8
+ - model: mistral:7b
9
+ - model: llama3.1:8b
10
+ - model: llava:7b
Binary file
Binary file
Binary file
Binary file
Binary file
llm_benchmark/main.py ADDED
@@ -0,0 +1,101 @@
1
+ import typer, base64
2
+ from llm_benchmark import check_models
3
+ from llm_benchmark import check_ollama
4
+ from llm_benchmark import run_benchmark
5
+
6
+ from .systeminfo import sysmain
7
+
8
+ from .security_connection import connection
9
+
10
+ import pkg_resources
11
+
12
+
13
+ app = typer.Typer()
14
+
15
+ @app.command()
16
+ def hello(name: str):
17
+ print(f"Hello {name}!")
18
+
19
+
20
+ @app.command()
21
+ def run(ollamabin: str = 'ollama' , sendinfo : bool = True ):
22
+ sys_info = sysmain.get_extra()
23
+ print(f"Total memory size : {sys_info['memory']:.2f} GB")
24
+ print(f"cpu_info: {sys_info['cpu']}")
25
+ print(f"gpu_info: {sys_info['gpu']}")
26
+ print(f"os_version: {sys_info['os_version']}")
27
+
28
+ ollama_version = check_ollama.check_ollama_version(ollamabin)
29
+ print(f"ollama_version: {ollama_version}")
30
+ print('-'*10)
31
+
32
+ ft_mem_size = float(f"{sys_info['memory']:.2f}")
33
+ models_file_path = pkg_resources.resource_filename('llm_benchmark','data/benchmark_models_16gb_ram.yml')
34
+ if(ft_mem_size>=1 and ft_mem_size <2):
35
+ models_file_path = pkg_resources.resource_filename('llm_benchmark','data/benchmark_models_2gb_ram.yml')
36
+ elif(ft_mem_size>=2 and ft_mem_size <4):
37
+ models_file_path = pkg_resources.resource_filename('llm_benchmark','data/benchmark_models_3gb_ram.yml')
38
+ elif(ft_mem_size>=4 and ft_mem_size <7):
39
+ models_file_path = pkg_resources.resource_filename('llm_benchmark','data/benchmark_models_4gb_ram.yml')
40
+ elif(ft_mem_size>=7 and ft_mem_size <15):
41
+ models_file_path = pkg_resources.resource_filename('llm_benchmark','data/benchmark_models_8gb_ram.yml')
42
+
43
+ check_models.pull_models(models_file_path)
44
+ print('-'*10)
45
+
46
+ benchmark_file_path = pkg_resources.resource_filename('llm_benchmark','data/benchmark1.yml')
47
+
48
+ bench_results_info = {}
49
+ is_simulation = False
50
+ if is_simulation==False :
51
+ result1 = run_benchmark.run_benchmark(models_file_path,benchmark_file_path, 'instruct', ollamabin)
52
+ bench_results_info.update(result1)
53
+ result2 = run_benchmark.run_benchmark(models_file_path,benchmark_file_path, 'question-answer', ollamabin)
54
+ bench_results_info.update(result2)
55
+ result3 = run_benchmark.run_benchmark(models_file_path,benchmark_file_path, 'vision-image', ollamabin)
56
+ bench_results_info.update(result3)
57
+ else:
58
+ bench_results_info.update({"llama2:7b":7.65})
59
+ bench_results_info.update({"gemma2:7b":17.77})
60
+
61
+ if (sendinfo==True):
62
+ print(f"Sending the following data to a remote server")
63
+ print(f"Your machine UUID : {sysmain.get_uuid()}")
64
+ #print(f"{bench_results_info.items()}")
65
+ x = connection.send_benchmark(sysmain.get_uuid(),ollama_version,bench_results_info)
66
+ #print(x)
67
+ print('=='*10)
68
+ #print(f"{sys_info.items()}")
69
+ sys_info = sysmain.get_extra()
70
+ sys_info['uuid']=f"{sysmain.get_uuid()}"
71
+ x = connection.send_sysinfo(sys_info)
72
+ #print(x)
73
+
74
+
75
+ @app.command()
76
+ def goodbye(name: str, formal: bool = False):
77
+ if formal:
78
+ print(f"Goodbye Mr.(Ms.) {name}. Have a good day.")
79
+ else:
80
+ print(f"Bye {name}!")
81
+
82
+ @app.command()
83
+ def sysinfo(formal: bool = True):
84
+ if formal:
85
+ sys_info = sysmain.get_extra()
86
+ sys_info['uuid'] = f"{sysmain.get_uuid()}"
87
+ #print(sys_info.items())
88
+ print(f"memory : {sys_info['memory']:.2f} GB")
89
+ print(f"cpu_info: {sys_info['cpu']}")
90
+ print(f"gpu_info: {sys_info['gpu']}")
91
+ print(f"os_version: {sys_info['os_version']}")
92
+ print(f"Your machine UUID : {sys_info['uuid']}")
93
+
94
+ x = connection.send_sysinfo(sys_info)
95
+ print(x)
96
+ else:
97
+ print(f"No print!")
98
+
99
+
100
+ if __name__ == "__main__":
101
+ app()
@@ -0,0 +1,50 @@
1
+ import requests
2
+
3
+ headers = {
4
+ 'Content-Type': 'application/json',
5
+ }
6
+ #"model" : "phi"
7
+ #"model" : "llama2"
8
+ #"model" : "mistral"
9
+
10
+ data = '{\n "model": "llama2:7b",\n "prompt": "Why is the sky blue? Is it related to sunshine?",\n "stream": false\n}'
11
+
12
+ response = requests.post('http://localhost:11434/api/generate', headers=headers, data=data)
13
+ jsonResponse = response.json()
14
+
15
+ model = ""
16
+ total_duration = 0.0
17
+ load_duration = 0.0
18
+ prompt_eval_count = 0
19
+ prompt_eval_duration = 0.0
20
+ eval_count = 0
21
+ eval_duration = 0.0
22
+ for key, value in jsonResponse.items():
23
+ if (key=="response"):
24
+ pass
25
+ elif (key=="context"):
26
+ pass
27
+ elif (key=="model"):
28
+ model = value
29
+ elif (key=="total_duration"):
30
+ total_duration = float(value)/(10**6)
31
+ elif (key=="load_duration"):
32
+ load_duration = float(value)/(10**6)
33
+ elif (key=="prompt_eval_count"):
34
+ prompt_eval_count=int(value)
35
+ elif (key=="prompt_eval_duration"):
36
+ prompt_eval_duration=float(value)/(10**6)
37
+ elif (key=="eval_count"):
38
+ eval_count=int(value)
39
+ elif (key=="eval_duration"):
40
+ eval_duration=float(value)/(10**6)
41
+
42
+ print(f"model = {model}")
43
+
44
+ print(f"{'total_duration time': >20} = {total_duration:10.2f} ms")
45
+ print(f"{'load_duration time': >20} = {load_duration:10.2f} ms")
46
+
47
+ print(f"{'prompt eval time ': >20} = {prompt_eval_duration:10.2f} ms / {prompt_eval_count:>6} tokens")
48
+ print(f"{'eval time ': >20} = {eval_duration:10.2f} ms / {eval_count:>6} tokens ")
49
+ print(f"Performance: {eval_count/eval_duration*1000:10.2f}(tokens/s)")
50
+
@@ -0,0 +1,119 @@
1
+ import argparse
2
+ import yaml
3
+ import subprocess
4
+ import datetime
5
+ import pkg_resources
6
+
7
+ parser = argparse.ArgumentParser(
8
+ prog="python3 check_models.py",
9
+ description="Before running check_models.py, please make sure you installed ollama successfully \
10
+ on macOS, Linux, or WSL2 on Windows. You can check the website: https://ollama.com",
11
+ epilog="Author: Jason Chuang")
12
+
13
+ parser.add_argument("-v",
14
+ "--verbose",
15
+ action="store_true",
16
+ help="this program helps you check whether you have ollama benchmark models installed")
17
+
18
+ parser.add_argument("-m",
19
+ "--models",
20
+ type=str,
21
+ help="provide benchmark models YAML file path. ex. ../data/benchmark_models.yml")
22
+
23
+ parser.add_argument("-b",
24
+ "--benchmark",
25
+ type=str,
26
+ help="provide benchmark YAML file path. ex. ../data/benchmark1.yml")
27
+
28
+ parser.add_argument("-t",
29
+ "--type",
30
+ type=str,
31
+ help="provide benchmark model type. ex, instruct")
32
+
33
+
34
+ def parse_yaml(yaml_file_path):
35
+ with open(yaml_file_path, 'r') as stream:
36
+ try:
37
+ data=yaml.safe_load(stream)
38
+ #print(d)
39
+ except yaml.YAMLError as e:
40
+ print(e)
41
+ return data
42
+
43
+ def run_benchmark(models_file_path, benchmark_file_path, type, ollamabin):
44
+
45
+ models_dict = parse_yaml(models_file_path)
46
+ benchmark_dict = parse_yaml(benchmark_file_path)
47
+ model_type = type
48
+ allowed_models = {e['model'] for e in models_dict['models']}
49
+ #print(allowed_models)
50
+ ans={}
51
+ # Writing to file
52
+ for one_model_type in benchmark_dict['modeltypes']:
53
+ #print(one_model_type)
54
+ if (one_model_type['type']==model_type):
55
+ #print(one_model_type['models'])
56
+ #print(one_model_type['prompts'])
57
+ for onemodel in one_model_type['models']:
58
+ if (onemodel['model'] in allowed_models ):
59
+ loc_dt = datetime.datetime.today()
60
+ with open(f'log_{loc_dt.strftime("%Y-%m-%d-%H%M%S")}.log', "w", encoding='utf-8') as file1:
61
+ #print(onemodel)
62
+ stored_nums=[]
63
+ model_name = onemodel['model']
64
+ print(f'model_name = {model_name}')
65
+ file1.write(f'\nmodel_name = {model_name}\n')
66
+
67
+ if model_name.startswith('llava'):
68
+ for one_prompt in one_model_type['prompts']:
69
+ img_file_names = one_prompt['keywords'].split(',')
70
+ for img in img_file_names:
71
+ img_file_path = pkg_resources.resource_filename('llm_benchmark',f'data/img/{img}')
72
+ prompt = f"{one_prompt['prompt']} {img_file_path}"
73
+ print(f"prompt = {prompt}")
74
+ result = subprocess.run([ollamabin, 'run', model_name, one_prompt['prompt'],'--verbose'], capture_output=True, text=True, check=True, encoding='utf-8')
75
+ std_err = result.stderr
76
+ #print(result.stderr)
77
+ file1.write(std_err)
78
+
79
+ for line in std_err.split('\n'):
80
+ if ('eval rate' in line) and ('prompt' not in line):
81
+ print(line)
82
+ number = float(line[-20:-8])
83
+ stored_nums.append(number)
84
+ #print(number)
85
+ else:
86
+ for one_prompt in one_model_type['prompts']:
87
+ print(f"prompt = {one_prompt['prompt']}")
88
+ result = subprocess.run([ollamabin, 'run', model_name, one_prompt['prompt'],'--verbose'], capture_output=True, text=True, check=True, encoding='utf-8')
89
+ std_err = result.stderr
90
+ #print(result.stderr)
91
+ file1.write(std_err)
92
+
93
+ for line in std_err.split('\n'):
94
+ if ('eval rate' in line) and ('prompt' not in line):
95
+ print(line)
96
+ number = float(line[-20:-8])
97
+ stored_nums.append(number)
98
+ #print(number)
99
+
100
+ print("-"*20)
101
+ if(len(stored_nums)!=0):
102
+ average = sum(stored_nums)/len(stored_nums)
103
+ print("Average of eval rate: ", round(average,3), " tokens/s")
104
+ ans[f"{model_name}"]=f"{round(average,3):.2f}"
105
+
106
+ print("-"*40)
107
+ file1.write("\n"+"-"*40)
108
+ file1.close()
109
+
110
+ return ans
111
+
112
+ if __name__ == "__main__":
113
+ args = parser.parse_args()
114
+ #print(f"args.verbose value:{args.verbose}")
115
+ if (args.models is not None) and (args.benchmark is not None) and (args.type is not None):
116
+ run_benchmark(args.models, args.benchmark, args.type)
117
+ print('-'*40)
118
+
119
+
@@ -0,0 +1,59 @@
1
+ import argparse
2
+ import yaml
3
+ import subprocess
4
+ import datetime
5
+
6
+ parser = argparse.ArgumentParser(
7
+ prog="python3 check_models.py",
8
+ description="Before running check_models.py, please make sure you installed ollama successfully \
9
+ on macOS, Linux, or WSL2 on Windows. You can check the website: https://ollama.ai",
10
+ epilog="Author: Jason Chuang")
11
+
12
+ parser.add_argument("-v",
13
+ "--verbose",
14
+ action="store_true",
15
+ help="this program helps you check whether you have ollama benchmark models installed")
16
+
17
+ parser.add_argument("-m",
18
+ "--models",
19
+ type=str,
20
+ help="provide benchmark models YAML file path. ex. ../data/benchmark_models.yml")
21
+
22
+ def parse_yaml(yaml_file_path):
23
+ with open(yaml_file_path, 'r') as stream:
24
+ try:
25
+ data=yaml.safe_load(stream)
26
+ #print(d)
27
+ except yaml.YAMLError as e:
28
+ print(e)
29
+ return data
30
+
31
+ if __name__ == "__main__":
32
+ args = parser.parse_args()
33
+ #print(f"args.verbose value:{args.verbose}")
34
+ if (args.models is not None):
35
+ #print(f"args.models file path:{args.models}")
36
+ models_dict = parse_yaml(args.models)
37
+
38
+ loc_dt = datetime.datetime.today()
39
+ # Writing to file
40
+ with open(f'log_{loc_dt.strftime("%Y-%m-%d-%H%M%S")}.log', "w") as file1:
41
+ for onemodel in models_dict['models']:
42
+ model_name = onemodel['model']
43
+ print(f'model_name = {model_name}')
44
+ file1.write(f'\nmodel_name = {model_name}\n')
45
+
46
+ result = subprocess.run(['ollama', 'run', model_name,f'"Why is the sky blue?"','--verbose'], capture_output=True, text=True, check=True)
47
+ std_err = result.stderr
48
+ #print(result.stderr)
49
+ file1.write(std_err)
50
+
51
+ for line in std_err.split('\n'):
52
+ if ('eval rate' in line) and ('prompt' not in line):
53
+ print(line)
54
+ number = float(line[-20:-8])
55
+ print(number)
56
+
57
+
58
+ print("-"*40)
59
+ file1.write("\n"+"-"*40)
File without changes
@@ -0,0 +1,30 @@
1
+ import requests,json
2
+
3
+
4
+ remote_server = "http://llm.aidatatools.com"
5
+ #emote_server = "http://localhost:5000"
6
+
7
+ def send_sysinfo(data_dict):
8
+
9
+ json_object = json.dumps(data_dict, indent = 4)
10
+ print(json_object)
11
+ print('-'*10)
12
+
13
+ url = f'{remote_server}/api/receiver.php'
14
+
15
+ x = requests.post(url, data = json_object)
16
+
17
+ return x.text
18
+
19
+ def send_benchmark(uuid, ollama_version,data_dict):
20
+ data_dict.update({"uuid":f"{uuid}"})
21
+ data_dict.update({"ollama_version":f"{ollama_version}"})
22
+ json_object = json.dumps(data_dict, indent = 4)
23
+ print(json_object)
24
+ print('-'*10)
25
+
26
+ url = f'{remote_server}/api/receiver_benchmark.php'
27
+
28
+ x = requests.post(url, data = json_object)
29
+
30
+ return x.text
File without changes
File without changes
@@ -0,0 +1,242 @@
1
+ import platform
2
+ import psutil
3
+ import GPUtil
4
+ import subprocess
5
+ import os
6
+ import uuid
7
+ import base64
8
+
9
+ def get_total_memory_size():
10
+ memory_info = psutil.virtual_memory()
11
+ return (memory_info.total/(2**(10*3)))
12
+
13
+ def get_system_info():
14
+ #print("System Information:")
15
+ system_info = platform.uname()
16
+ ans={}
17
+ ans['system'] = f"{system_info.system}"
18
+ ans['node_name'] = f"{system_info.node}"
19
+ ans['release'] = f"{system_info.release}"
20
+ ans['version'] = f"{system_info.version}"
21
+ ans['machine'] = f"{system_info.machine}"
22
+ ans['processor'] = f"{system_info.processor}"
23
+ return ans
24
+
25
+ def get_cpu_info():
26
+ cpu_info = platform.processor()
27
+ cpu_count = psutil.cpu_count(logical=False)
28
+ logical_cpu_count = psutil.cpu_count(logical=True)
29
+
30
+ #print("\nCPU Information:")
31
+ ans = {}
32
+ ans['processor'] = f"{cpu_info}"
33
+ ans['physical_cores'] = f"{cpu_count}"
34
+ ans['logical_cores'] = f"{logical_cpu_count}"
35
+ return ans
36
+
37
+ def get_memory_info():
38
+ memory_info = psutil.virtual_memory()
39
+
40
+ #print("\nMemory Information: Unit : bytes")
41
+ ans={}
42
+ ans['total_memory'] = f"{memory_info.total}"
43
+ ans['available_memory'] = f"{memory_info.available}"
44
+ ans['used_memory'] = f"{memory_info.used}"
45
+ ans['memory_utilization'] = f"{memory_info.percent:.2f}%"
46
+ return ans
47
+
48
+ def get_disk_info():
49
+ disk_info = psutil.disk_usage('/')
50
+
51
+ #print("\nDisk Information: Unit : bytes")
52
+ ans={}
53
+ ans['total_disk_space'] = f"{disk_info.total}"
54
+ ans['used_disk_space'] = f"{disk_info.used}"
55
+ ans['free_disk_space'] = f"{disk_info.free}"
56
+ ans['disk_space_utilization'] = f" {disk_info.percent:.2f}%"
57
+
58
+ #Only Nvidia GPU on Windows and Linux
59
+ def get_gpu_info():
60
+
61
+ ans={}
62
+ if (get_system_info()['system']=='Darwin'):
63
+ ans['0'] = "no_gpu"
64
+ return ans
65
+ else:
66
+ gpus = GPUtil.getGPUs()
67
+
68
+ if not gpus:
69
+ print("\nNo GPU detected.")
70
+ ans['0'] = "no_gpu"
71
+ else:
72
+ ans['0'] = "there_is_gpu"
73
+
74
+ for i, gpu in enumerate(gpus):
75
+ #print(f"\nGPU {i + 1} Information:")
76
+ ans[f'{i+1}'] = {}
77
+ ans[f'{i+1}']['id'] = f"{gpu.id}"
78
+ ans[f'{i+1}']['name'] = f"{' '.join(gpu.name.splitlines())}"
79
+ ans[f'{i+1}']['driver'] = f"{gpu.driver}"
80
+ ans[f'{i+1}']['gpu_memory_total'] = f"{gpu.memoryTotal} MB"
81
+ ans[f'{i+1}']['gpu_memory_free'] = f"{gpu.memoryFree} MB"
82
+ ans[f'{i+1}']['gpu_memory_used'] = f"{gpu.memoryUsed} MB"
83
+ ans[f'{i+1}']['gpu_load'] = f"{gpu.load*100}%"
84
+ ans[f'{i+1}']['gpu_temperature'] = f"{gpu.temperature}°C"
85
+
86
+ return ans
87
+
88
+ def check_windows_shell():
89
+ parent_pid = os.getppid()
90
+ shell_name = psutil.Process(parent_pid).name().lower()
91
+ if 'cmd' in shell_name:
92
+ return 'CMD'
93
+ elif 'powershell' in shell_name:
94
+ return 'PowerShell'
95
+ else:
96
+ return 'Unknown'
97
+
98
+
99
+ def get_extra():
100
+ system_info = platform.uname()
101
+ ans={}
102
+ ans['system'] = f"{system_info.system}"
103
+ ans['memory'] = get_total_memory_size()
104
+ ans['cpu'] = f"unknown"
105
+ ans['gpu'] = f"unknown"
106
+ ans['os_version'] = f"unknown"
107
+
108
+ try:
109
+ if(system_info.system=='Darwin'):
110
+ ans['system_name'] = "macOS"
111
+
112
+ print('----------Apple Mac---------')
113
+ r1 = subprocess.run(['system_profiler', 'SPHardwareDataType'],capture_output=True,text=True)
114
+ #ans['hardware'] = f"{r1.stdout}"
115
+ for line in r1.stdout.split('\n'):
116
+ if('Model Identifier' in line):
117
+ ans['model']=f"{line[24:]}"
118
+
119
+
120
+ for line in r1.stdout.split('\n'):
121
+ if ('Chip' in line):
122
+ ans['cpu']=f"{line[12:]}"
123
+
124
+ if(ans['cpu'].startswith('Apple')):
125
+ ans['gpu'] = ans['cpu']
126
+ else:
127
+ ans['gpu'] = 'no_gpu'
128
+
129
+ #r2 = subprocess.run(['system_profiler', 'SPDisplaysDataType'],capture_output=True,text=True)
130
+ #ans['display'] = f"{r2.stdout}"
131
+ r3 = subprocess.run(['system_profiler', 'SPSoftwareDataType'],capture_output=True,text=True)
132
+ #ans['software'] = f"{r3.stdout}"
133
+
134
+ for line in r3.stdout.split('\n'):
135
+ if ('System Version' in line):
136
+ ans['os_version']=f"{line[22:]}"
137
+ return ans
138
+ elif(system_info.system=='Linux'):
139
+ ans['system_name'] = "Linux"
140
+
141
+ print('-------Linux----------')
142
+
143
+ try:
144
+ r2 = subprocess.run(['lsb_release','-a'],capture_output=True,text=True)
145
+ software = f"{r2.stdout}"
146
+ for line in software.split('\n'):
147
+ if ('Description' in line):
148
+ ans['os_version']=f"{line[12:]}".strip()
149
+ except:
150
+ r2 = subprocess.run(['cat','/etc/os-release'],capture_output=True,text=True)
151
+ software = f"{r2.stdout}"
152
+ for line in software.split('\n'):
153
+ if ('PRETTY_NAME' in line):
154
+ ans['os_version']=f"{line[12:]}".strip()
155
+
156
+ try:
157
+ r1 = subprocess.run(['lshw','-C','cpu'],capture_output=True,text=True)
158
+ for line in r1.stdout.split('\n'):
159
+ if ('product' in line):
160
+ ans['cpu']=f"{line[16:]}"
161
+ except:
162
+ cmd = ['lscpu']
163
+ ps = subprocess.Popen(cmd, stdout=subprocess.PIPE)
164
+ cmd = ['grep', 'Model name']
165
+ grep = subprocess.Popen(cmd, stdin=ps.stdout, stdout=subprocess.PIPE,
166
+ encoding='utf-8')
167
+ ps.stdout.close()
168
+ output, _ = grep.communicate()
169
+ python_processes = output.split('\n')
170
+ ans['cpu'] = python_processes[0][16:].strip()
171
+
172
+ if (get_gpu_info()['0']=='no_gpu'):
173
+ try:
174
+ r2 = subprocess.run(['lshw','-C','display'],capture_output=True,text=True)
175
+ for line in r2.stdout.split('\n'):
176
+ if ('product' in line):
177
+ ans['gpu']=f"{line[16:]}"
178
+ except:
179
+ ans['gpu']="no_gpu"
180
+ else :
181
+ print(f"{get_gpu_info()['1']}")
182
+ try:
183
+ print(get_gpu_info()['2'])
184
+ print('At least two GPU cards')
185
+ except:
186
+ print('Only one GPU card')
187
+ #List only the first gpu name
188
+ ans['gpu']=get_gpu_info()['1']['name']
189
+
190
+
191
+ return ans
192
+
193
+ elif(system_info.system=='Windows'):
194
+ ans['system_name'] = "Windows"
195
+
196
+ prefix_exe='powershell.exe'
197
+ #print("Python is running in:", check_windows_shell(), "on Windows")
198
+ ans['run_in'] = f"{check_windows_shell()}"
199
+
200
+ r1 = subprocess.run([prefix_exe,'Get-WmiObject','Win32_Processor'],capture_output=True,text=True)
201
+ #print(r1.stdout)
202
+ r_cpu = subprocess.run([prefix_exe,'(Get-WmiObject Win32_Processor).Name'],capture_output=True,text=True)
203
+ #print(r_cpu.stdout)
204
+ ans['cpu']=r_cpu.stdout.strip()
205
+ r2 = subprocess.run([prefix_exe,'Get-WmiObject','Win32_PhysicalMemory'],capture_output=True,text=True)
206
+ #print(r2.stdout)
207
+ r3 = subprocess.run([prefix_exe,'Get-WmiObject','Win32_VideoController'],capture_output=True,text=True)
208
+ #print(r3.stdout)
209
+ r_gpu = subprocess.run([prefix_exe,'(Get-WmiObject Win32_VideoController).Caption'],capture_output=True,text=True)
210
+ str_gpu = r_gpu.stdout.strip()
211
+ str_gpu = ' '.join(str_gpu.splitlines())
212
+ #print(r_gpu)
213
+ ans['gpu'] = str_gpu
214
+ r4 = subprocess.run([prefix_exe,'(Get-WmiObject Win32_OperatingSystem).Caption'],capture_output=True,text=True)
215
+ #print(r4.stdout)
216
+ ans['os_version'] = f"{r4.stdout}"
217
+
218
+ return ans
219
+
220
+ except:
221
+ print("error! when retrieving os_version, cpu, or gpu !")
222
+
223
+ return ans
224
+
225
+ def get_uuid():
226
+ sys_info = get_extra()
227
+ system_name = sys_info['system_name']
228
+ cpu = sys_info['cpu']
229
+ gpu = sys_info['gpu']
230
+ memory = f"{sys_info['memory']:.2f}"
231
+
232
+ id_str = f"{system_name}|{cpu}|{gpu}|{memory}"
233
+ #print(id_str)
234
+ uuid5 = uuid.uuid5(uuid.NAMESPACE_X500, id_str)
235
+ return uuid5
236
+
237
+ if __name__ == "__main__":
238
+ #sysinfo = get_extra()
239
+ uuid5 = get_uuid()
240
+ print("UUID version 5:", uuid5)
241
+
242
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 aidatatools (Jason Chuang)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,147 @@
1
+ Metadata-Version: 2.2
2
+ Name: llm_benchmark
3
+ Version: 0.3.27
4
+ Summary: LLM Benchmark
5
+ Home-page: https://github.com/aidatatools/ollama-benchmark
6
+ Author: Jason Chuang
7
+ Author-email: chuangtcee@gmail.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.9
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: click>=8.0.0
15
+ Requires-Dist: typer==0.11.0
16
+ Requires-Dist: ollama==0.2.1
17
+ Requires-Dist: pyyaml==6.0.1
18
+ Requires-Dist: requests==2.31.0
19
+ Requires-Dist: psutil==5.9.8
20
+ Requires-Dist: GPUtil==1.4.0
21
+ Requires-Dist: lib-platform==1.2.10
22
+ Requires-Dist: setuptools==69.1.0
23
+ Dynamic: author
24
+ Dynamic: author-email
25
+ Dynamic: classifier
26
+ Dynamic: description
27
+ Dynamic: description-content-type
28
+ Dynamic: home-page
29
+ Dynamic: requires-dist
30
+ Dynamic: requires-python
31
+ Dynamic: summary
32
+
33
+ # llm-benchmark (ollama-benchmark)
34
+
35
+ LLM Benchmark for Throughput via Ollama (Local LLMs)
36
+
37
+ ## Installation prerequisites
38
+
39
+ Working [Ollama](https://ollama.com) installation.
40
+
41
+ ## Installation Steps
42
+
43
+ Depending on your python setup either
44
+ ```bash
45
+ pip install llm-benchmark
46
+ ```
47
+ or
48
+ ```bash
49
+ pipx install llm-benchmark
50
+ ```
51
+
52
+ ## Usage for general users directly
53
+
54
+ ```bash
55
+ llm_benchmark run
56
+ ```
57
+
58
+ ## Installation and Usage in Video format
59
+
60
+ ![llm-benchmark](https://github.com/aidatatools/ollama-benchmark/blob/main/llm-benchmark.gif)
61
+
62
+ It's tested on Python 3.9 and above.
63
+
64
+ ## ollama installation with the following models installed
65
+
66
+ 7B model can be run on machines with 8GB of RAM
67
+
68
+ 13B model can be run on machines with 16GB of RAM
69
+
70
+ ## Usage explaination
71
+
72
+ On Windows, Linux, and macOS, it will detect memory RAM size to first download required LLM models.
73
+
74
+ When memory RAM size is greater than or equal to 4GB, but less than 7GB, it will check if gemma:2b exist. The program implicitly pull the model.
75
+
76
+ ```bash
77
+ ollama pull qwen:1.8b
78
+ ollama pull gemma:2b
79
+ ollama pull phi:2.7b
80
+ ollama pull phi3:3.8b
81
+ ```
82
+
83
+ When memory RAM size is greater than 7GB, but less than 15GB, it will check if these models exist. The program implicitly pull these models
84
+
85
+ ```bash
86
+ ollama pull phi3:3.8b
87
+ ollama pull qwen2:7b
88
+ ollama pull gemma2:9b
89
+ ollama pull mistral:7b
90
+ ollama pull llama3.1:8b
91
+ ollama pull llava:7b
92
+ ```
93
+
94
+ When memory RAM siz is greater than 15GB, it will check if these models exist. The program implicitly pull these models
95
+
96
+ ```bash
97
+ ollama pull phi4:14b
98
+ ollama pull qwen2:7b
99
+ ollama pull gemma2:9b
100
+ ollama pull mistral:7b
101
+ ollama pull llama3.1:8b
102
+ ollama pull llava:7b
103
+ ollama pull llava:13b
104
+ ```
105
+
106
+ ## Python Poetry manually(advanced) installation
107
+
108
+ <https://python-poetry.org/docs/#installing-manually>
109
+
110
+ ## For developers to develop new features on Windows Powershell or on Ubuntu Linux or macOS
111
+
112
+ ```bash
113
+ python3 -m venv .venv
114
+ . ./.venv/bin/activate
115
+ pip install -U pip setuptools
116
+ pip install poetry
117
+ ```
118
+
119
+ ## Usage in Python virtual environment
120
+
121
+ ```bash
122
+ poetry shell
123
+ poetry install
124
+ llm_benchmark hello jason
125
+ ```
126
+
127
+ ### Example #1 send systeminfo and benchmark results to a remote server
128
+
129
+ ```bash
130
+ llm_benchmark run
131
+ ```
132
+
133
+ ### Example #2 Do not send systeminfo and benchmark results to a remote server
134
+
135
+ ```bash
136
+ llm_benchmark run --no-sendinfo
137
+ ```
138
+
139
+ ### Example #3 Benchmark run on explicitly given the path to the ollama executable (When you built your own developer version of ollama)
140
+
141
+ ```bash
142
+ llm_benchmark run --ollamabin=~/code/ollama/ollama
143
+ ```
144
+
145
+ ## Reference
146
+
147
+ [Ollama](https://ollama.com)
@@ -0,0 +1,29 @@
1
+ llm_benchmark/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ llm_benchmark/check_models.py,sha256=plcAUqp8953j9MFHoAPJHN9AxzhE9pYVjTN7luML_2k,1837
3
+ llm_benchmark/check_ollama.py,sha256=VyMLzWj5O6RjeFeijxFQXjzj0_enf4O-r5bsRnj_AnA,693
4
+ llm_benchmark/main.py,sha256=17Pks6EOSjqzJW_WwqpwtqkYEdQehwTkI_Ka6hoNSR0,3682
5
+ llm_benchmark/query_llm.py,sha256=1g_RZPTnL-rMs0dfBXPlBmUUxutpRG1bCj_R9eSppnY,1623
6
+ llm_benchmark/run_benchmark.py,sha256=CSYgbOogQvwbuDSzNU_H2I2LxHpKv2ZC8sR7Cl70i1I,5797
7
+ llm_benchmark/run_benchmark_one.py,sha256=FSqrdx5wM5f36kggYBlhs6SF9DERaiiRr8TO1Y6FOKk,2338
8
+ llm_benchmark/data/benchmark1.yml,sha256=VEPaCvuD4hl-Ls6Nx4-kk29RliXFccXog-w2wevWwpI,2192
9
+ llm_benchmark/data/benchmark_models_16gb_ram.yml,sha256=vpuh_OvP4OVFd8fVkY10qH7QMi5pRJvyZx9R9bih36s,217
10
+ llm_benchmark/data/benchmark_models_2gb_ram.yml,sha256=eQHxZfXnHSgfgPSxj6yKdPSiEbE-ayMGeJTTXSunqvs,101
11
+ llm_benchmark/data/benchmark_models_3gb_ram.yml,sha256=7n3BTVdTIvZOvFZwfo_FUB_UtexD5XoPg6NpX5YZoLc,121
12
+ llm_benchmark/data/benchmark_models_4gb_ram.yml,sha256=E85cugjAbeVXAnvKhe77VtZJ69x-guKOEUP2l3q5fLk,142
13
+ llm_benchmark/data/benchmark_models_8gb_ram.yml,sha256=Ot3xfeezL5K65V0GC8ha9HOvtF8qSUk1A-71W4eQpo8,196
14
+ llm_benchmark/data/img/sample1.jpg,sha256=q7ABTbWXdWrVqxmMiDjRmvKaXa8Ewckm4T3jmby09Vs,596759
15
+ llm_benchmark/data/img/sample2.jpg,sha256=wYKHxYbsIScnP07_4X_iC_w0reIU-HNeSUw239yf-P0,243536
16
+ llm_benchmark/data/img/sample3.jpg,sha256=UyFxJvw1DvZK-wzFVyu0tRQ-cX8MJnOz79KDyQSfn3E,518611
17
+ llm_benchmark/data/img/sample4.jpg,sha256=t3VIGACJfMuHRPjdJEUKiwWquZSYnFYN09OXeCopO8I,236523
18
+ llm_benchmark/data/img/sample5.jpg,sha256=rEAvbm2qrAJ2-UxurdHGfeStjx2KsNkJj_TEKAOfyTs,534025
19
+ llm_benchmark/security_connection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ llm_benchmark/security_connection/connection.py,sha256=KbAXzsoKmDsMO_gIJgIWFLgm0xP23dirpWSg2Yb_2zw,723
21
+ llm_benchmark/security_connection/security.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ llm_benchmark/systeminfo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
+ llm_benchmark/systeminfo/sysmain.py,sha256=AfIyGO3-S8JfFe2F6hQBD5CtJjXv_lyBIcjH_mI4PiM,8715
24
+ llm_benchmark-0.3.27.dist-info/LICENSE,sha256=k_4utRVOlpXU23bis0RwhxbUOH84fxg37__WQ_pxzVY,1083
25
+ llm_benchmark-0.3.27.dist-info/METADATA,sha256=5U73M2I3shy6IUJYhqNzmPAn6LASkbk5I5pCk3J45Gk,3449
26
+ llm_benchmark-0.3.27.dist-info/WHEEL,sha256=9Hm2OB-j1QcCUq9Jguht7ayGIIZBRTdOXD1qg9cCgPM,109
27
+ llm_benchmark-0.3.27.dist-info/entry_points.txt,sha256=JMAtMpNNt4cq0iB0z35kOP6tz-i3HmvtP9X6CtLHhyw,57
28
+ llm_benchmark-0.3.27.dist-info/top_level.txt,sha256=SQ0wiRPk2zxai1IPFl5pDctlKZ19OJKZUKF1kJpbdHA,14
29
+ llm_benchmark-0.3.27.dist-info/RECORD,,
@@ -0,0 +1,6 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (75.8.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py2-none-any
5
+ Tag: py3-none-any
6
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ llm_benchmark = llm_benchmark.main:app
@@ -0,0 +1 @@
1
+ llm_benchmark