基于LLM的优化器评测
- 求解的目标函数
- 测试结果
- 测试代码
- 测试日志
背景:
很多时候我们需要为系统寻找最优的超参.比如模型训练,推理的量化等.本文尝试将LLM当成优化器,帮忙我们寻找最优的超参.
验证方法:
- 1.设计一个已知最优解的多项式,该多项式有3个变量(因为3个变量可以通过plot_surface+时间的方式可视化)
- 2.通过多轮对话的方式,让LLM根据我们的反馈输出下一组最优解,找到最优解后退出
- 3.测试不同的LLM供应商,比较其寻找最优超参的效率
- 4.测试了随机梯度下降算法、遗传算法、模拟退火算法、贝叶斯算法
求解的目标函数
测试结果
模型 | 几次迭代 |
---|---|
dashscope(qwen-max) | 4 |
moonshot(kimi moonshot-v1-128k) | 6 |
qianfan(ERNIE-4.0-8K) | 5 |
sparkai(3.5) | 29>没有找到最优解 |
gemini(gemini-1.5-flash) | 3 |
azure(gpt-4o) | 6 |
遗传算法 | 50 |
模拟退火算法 | 351 |
pytorch随机梯度下降算法 | 10000>没有找到最优解 |
贝叶斯算法 | 27 |
测试代码
import re
import os
import logging
import random
import numpy as np
import os
logger = logging.getLogger('llm_logger')
logger.setLevel(logging.DEBUG) # 设置日志级别
# 创建一个handler,用于写入日志文件
log_file = 'llm_opt.log'
file_handler = logging.FileHandler(log_file)
file_handler.setLevel(logging.DEBUG)
# 创建一个handler,用于将日志输出到控制台
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
# 设置日志格式
formatter = logging.Formatter('%(message)s')
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)
# 将handlers添加到logger
logger.addHandler(file_handler)
logger.addHandler(console_handler)
system_prompt="你是一个人工助手,帮助用户进行参数优化"
constrain='''
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
'''
question =f'''
背景及需求:
我有二台8卡的GPU服务器手于训练一个LLM模型,因为不同的超参会导致不同的性能.我已经写好一个脚本,输入一些参数,运行脚本后,会输出训练的性能tokens/sec(这个值越大越好)。
我会告诉你有哪些输入参数以及它们的约束,你输出参数列表,之后我会利用你提供的参数列表运行训练脚本,得到tokens/sec,并将该值反馈给你。
你根据我的反馈,思考如何配置这些参数,可以让tokens/sec最大化。
通过这样不断的迭代,求出近似最优解
参数
1.HL_DP
2.HL_TP
3.HL_PP
{constrain}
明白我的要求了吗?,如果明白,请输出第一组参数列表
'''
import os
def objective_function(X,Y,Z):
if int(X)==2 and int(Y)==4 and int(Z)==2:
logger.info("find best var")
os._exit(0)
return 100*np.exp(-(X - 2)**2 - (Y - 4)**2 - (Z - 2)**2)
def run_script(output):
params=re.findall(r'\[(.*?)\]',output)
if len(params)>0:
params=params[-1]
match=re.findall(r'.*HL_DP=(\d+).*HL_TP=(\d+).*HL_PP=(\d+)',params)
if len(match)>0:
match=[int(x) for x in match[0]]
HL_DP,HL_TP,HL_PP=match
if HL_DP*HL_TP*HL_PP!=16:
return f"非法参数,请重新输入.{constrain}"
speed=objective_function(HL_DP,HL_TP,HL_PP)
return f"经过测试,上面参数对应的性能为tokens/sec:{speed:.3f},请给出新的参数配置"
return f"非法参数,请重新输入.{constrain}"
def moonshot():
logger.info("\n ######################## moonshot ######################## ")
'''
pip install --upgrade 'openai>=1.0'
https://platform.moonshot.cn/docs/api/chat#多轮对话
'''
MOONSHOT_API_KEY="sk-"
from openai import OpenAI
client = OpenAI(
api_key = MOONSHOT_API_KEY,
base_url = "https://api.moonshot.cn/v1",
)
history = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": question},
]
def chat(query, history):
if query is not None:
history.append({
"role": "user",
"content": query
})
completion = client.chat.completions.create(
model="moonshot-v1-128k",
messages=history,
temperature=0.3,
top_p=0.1
)
result = completion.choices[0].message.content
history.append({
"role": "assistant",
"content": result
})
return result
result=None
for i in range(30):
logger.info(f" ---------------------------------- iteration {i} ---------------------------------- ")
output=chat(result, history)
logger.info(output)
result= run_script(output)
logger.info(result)
def dashscope():
logger.info("\n ######################## dashscope ######################## ")
'''
https://help.aliyun.com/zh/dashscope/developer-reference/api-details?spm=a2c4g.11186623.0.0.45375120QTaSov
'''
from http import HTTPStatus
import dashscope
dashscope.api_key="sk-"
from dashscope import Generation
messages = [{'role': 'system', 'content': system_prompt},
{'role': 'user', 'content': question}]
for i in range(30):
logger.info(f" ---------------------------------- 第{i}轮 ---------------------------------- ")
response = Generation.call(model="qwen-max", messages=messages,result_format='message')
if response.status_code == HTTPStatus.OK:
messages.append({'role': response.output.choices[0]['message']['role'],
'content': response.output.choices[0]['message']['content']})
output=response.output.choices[0]['message']['content']
logger.info(output)
result=f"{run_script(output)}"
logger.info(result)
messages.append({"role":"user","content":result})
else:
logger.info('Request id: %s, Status code: %s, error code: %s, error message: %s' % (
response.request_id, response.status_code,
response.code, response.message
))
break
def qianfan():
logger.info("\n ######################## qianfan ######################## ")
import qianfan
os.environ["QIANFAN_AK"] = ""
os.environ["QIANFAN_SK"] = ""
'''
pip install qianfan
https://cloud.baidu.com/doc/WENXINWORKSHOP/s/clntwmv7t
'''
messages = [{'role': 'user', 'content': question}]
for i in range(30):
logger.info(f" ---------------------------------- 第{i}轮 ---------------------------------- ")
response = qianfan.ChatCompletion().do(endpoint="completions_pro", messages=messages,
temperature=0.7, top_p=0.8, penalty_score=1,
disable_search=False, enable_citation=False)
messages.append({'role': "assistant",'content': response.body["result"]})
output=response.body["result"]
logger.info(output)
result=f"{run_script(output)}"
logger.info(result)
messages.append({"role":"user","content":result})
def sparkai():
logger.info("\n ######################## sparkai ######################## ")
from sparkai.llm.llm import ChatSparkLLM, ChunkPrintHandler
from sparkai.core.messages import ChatMessage
'''
pip install --upgrade spark_ai_python
https://www.xfyun.cn/doc/spark/Web.html#_1-接口说明
'''
SPARKAI_URL = 'wss://spark-api.xf-yun.com/v3.5/chat'
SPARKAI_APP_ID = ''
SPARKAI_API_SECRET = ''
SPARKAI_API_KEY = ''
SPARKAI_DOMAIN = 'generalv3.5'
spark = ChatSparkLLM(
spark_api_url=SPARKAI_URL,
spark_app_id=SPARKAI_APP_ID,
spark_api_key=SPARKAI_API_KEY,
spark_api_secret=SPARKAI_API_SECRET,
spark_llm_domain=SPARKAI_DOMAIN,
streaming=False,
temperature=0.1
)
history = [
ChatMessage(role="system",content=system_prompt)
]
history.append(ChatMessage(role="user",content=question))
handler = ChunkPrintHandler()
for i in range(30):
logger.info(f" ---------------------------------- 第{i}轮 ----------------------------------")
a = spark.generate([history], callbacks=[handler])
history.append(a.generations[0][0].message)
output=a.generations[0][0].text
logger.info(output)
result=f"{run_script(output)}"
logger.info(result)
history.append(ChatMessage(role="user",content=result))
def gemini():
logger.info("\n ######################## gemini ######################## ")
'''
pip install google-generativeai
https://ai.google.dev/api/python/google/generativeai
'''
import google.generativeai as genai
genai.configure(api_key="")
model = genai.GenerativeModel('gemini-1.5-flash')
chat = model.start_chat(history=[])
response = chat.send_message(question)
for i in range(30):
logger.info(f" ---------------------------------- 第{i}轮 ----------------------------------")
output=response.text
logger.info(output)
result=f"{run_script(output)}"
logger.info(result)
response = chat.send_message(result)
def azure():
logger.info("\n ######################## azure ######################## ")
from openai import AzureOpenAI
endpoint = "https://xxx-completion.openai.azure.com/"
deployment = "gpt-4o"
client = AzureOpenAI(
azure_endpoint=endpoint,
api_key="",
api_version="2024-02-01",
)
messages=[
{
"role": "assistant",
"content": "你是一个人工助手,帮助用户进行参数优化"
},
{
"role": "user",
"content": question
}
]
response = client.chat.completions.create(model=deployment,messages=messages)
for i in range(30):
logger.info(f" ---------------------------------- 第{i}轮 ----------------------------------")
output = response.choices[0].message.content
messages.append({"role": "assistant", "content": output})
logger.info(output)
result=f"{run_script(output)}"
messages.append({"role": "user", "content": result})
logger.info(result)
response = client.chat.completions.create(model=deployment,messages=messages)
def decode_chromosome(chromosome, bounds, num_genes):
""" 解码染色体为实际值 """
decoded_values = []
for i in range(len(bounds)):
binary_str = chromosome[i*num_genes:(i+1)*num_genes]
integer_value = int(''.join(map(str, binary_str)), 2)
value = int(bounds[i][0] + (bounds[i][1] - bounds[i][0]) * integer_value / (2**num_genes - 1))
decoded_values.append(value)
return decoded_values
def generate_population(size, num_genes, bounds):
""" 生成初代种群 """
population = []
for _ in range(size):
chromosome = np.random.randint(2, size=len(bounds) * num_genes).tolist()
population.append(chromosome)
return population
def fitness_function(chromosome, bounds, num_genes):
decoded_values = decode_chromosome(chromosome, bounds, num_genes)
return objective_function(*decoded_values)
def selection(population, fitnesses):
""" 轮盘赌选择 """
total_fitness = sum(fitnesses)
pick = np.random.uniform(0, total_fitness)
current = 0
for chrom, fit in zip(population, fitnesses):
current += fit
if current > pick:
return chrom
return population[-1]
def crossover(parent1, parent2, crossover_rate):
if np.random.rand() < crossover_rate:
point = np.random.randint(1, len(parent1) - 1)
child1 = parent1[:point] + parent2[point:]
child2 = parent2[:point] + parent1[point:]
return [child1, child2]
else:
return [parent1, parent2]
def mutate(chromosome, mutation_rate):
for i in range(len(chromosome)):
if np.random.rand() < mutation_rate:
chromosome[i] = 1 - chromosome[i]
def genetic_algorithm(objective_function, bounds, population_size, num_genes, generations, crossover_rate, mutation_rate):
population = generate_population(population_size, num_genes, bounds)
best_chromosome = None
best_fitness = -float('inf')
for generation in range(generations):
fitnesses = [fitness_function(chrom, bounds, num_genes) for chrom in population]
current_best_fitness = max(fitnesses)
if current_best_fitness > best_fitness:
best_fitness = current_best_fitness
logger.info(f"Generation {generation*len(population)}")
best_chromosome = population[fitnesses.index(best_fitness)]
new_population = []
for _ in range(population_size // 2):
parent1 = selection(population, fitnesses)
parent2 = selection(population, fitnesses)
offspring = crossover(parent1, parent2, crossover_rate)
new_population.extend(offspring)
for chrom in new_population:
mutate(chrom, mutation_rate)
population = new_population
best_values = decode_chromosome(best_chromosome, bounds, num_genes)
return best_values, best_fitness
def run_genetic_algorithm():
logger.info("\n ######################## genetic_algorithm ######################## ")
random.seed(0)
np.random.seed(0)
# 参数设置
bounds = [(1, 8), (1, 8), (1, 8)]
population_size = 50
num_genes = 16
generations = 1000
crossover_rate = 0.7
mutation_rate = 0.01
# 运行遗传算法
best_solution, best_value = genetic_algorithm(objective_function, bounds, population_size, num_genes, generations, crossover_rate, mutation_rate)
logger.info(f"最佳解: X={best_solution[0]}, Y={best_solution[1]}, Z={best_solution[2]}")
logger.info(f"最大值: {best_value}")
def simulated_annealing(objective_function, bounds, initial_temp, temp_min, alpha, max_iter):
# 初始化起始点
X = random.randint(*bounds['X'])
Y = random.randint(*bounds['Y'])
Z = random.randint(*bounds['Z'])
# 初始化当前解和当前最佳解
current_solution = (X, Y, Z)
current_solution=[int(x) for x in current_solution]
current_value = objective_function(*current_solution)
best_solution = current_solution
best_value = current_value
# 初始化温度
temp = initial_temp
for i in range(max_iter):
logger.info("iteration: %d" % i)
# 生成新的候选解
candidate_solution = (
np.clip(current_solution[0] + np.random.normal(0, 1), *bounds['X']),
np.clip(current_solution[1] + np.random.normal(0, 1), *bounds['Y']),
np.clip(current_solution[2] + np.random.normal(0, 1), *bounds['Z'])
)
candidate_solution=[int(x) for x in candidate_solution]
candidate_value = objective_function(*candidate_solution)
# 接受新解的概率
if candidate_value > current_value:
accept_probability = 1
else:
accept_probability = np.exp((candidate_value - current_value) / temp)
# 根据概率决定是否接受新解
if accept_probability > random.uniform(0, 1):
current_solution = candidate_solution
current_value = candidate_value
# 更新最佳解
if current_value > best_value:
best_solution = current_solution
best_value = current_value
# 温度逐渐降低
temp = max(temp_min, temp * alpha)
return best_solution, best_value
def run_simulated_annealing():
logger.info("\n ######################## run_simulated_annealing ######################## ")
random.seed(0)
np.random.seed(0)
# 定义搜索空间
bounds = {
'X': (1, 8),
'Y': (1, 8),
'Z': (1, 8)
}
# 模拟退火参数
initial_temp = 10000
temp_min = 1e-10
alpha = 0.99
max_iter = 10000
# 运行模拟退火算法
best_solution, best_value = simulated_annealing(objective_function, bounds, initial_temp, temp_min, alpha, max_iter)
logger.info(f"最佳解: X={best_solution[0]}, Y={best_solution[1]}, Z={best_solution[2]}")
logger.info(f"最大值: {best_value}")
def run_sgd():
logger.info("\n ######################## run_sgd ######################## ")
import torch
def function(X,Y,Z):
if X==2 and Y==4 and Z==2:
logger.info("find best var")
os._exit(0)
return 100*torch.exp(-(X - 2)**2 - (Y - 4)**2 - (Z - 2)**2)
# 定义搜索空间
bounds = {
'X': (1, 8),
'Y': (1, 8),
'Z': (1, 8)
}
# 初始点(随机在范围内选择)
X = torch.tensor([torch.rand(1).item() * (bounds['X'][1] - bounds['X'][0]) + bounds['X'][0]], requires_grad=True)
Y = torch.tensor([torch.rand(1).item() * (bounds['Y'][1] - bounds['Y'][0]) + bounds['Y'][0]], requires_grad=True)
Z = torch.tensor([torch.rand(1).item() * (bounds['Z'][1] - bounds['Z'][0]) + bounds['Z'][0]], requires_grad=True)
# 学习率和最大迭代次数
lr = 0.1
max_iter = 10000
optimizer = torch.optim.SGD([X, Y, Z], lr=lr)
for i in range(max_iter):
optimizer.zero_grad()
# 计算目标函数值
value = function(X, Y, Z)
# 反向传播计算梯度
loss = -value # 我们要最大化目标函数值,所以取负值进行最小化
loss.backward()
# 更新参数
optimizer.step()
# 梯度裁剪,确保解在边界内
with torch.no_grad():
X.clamp_(bounds['X'][0], bounds['X'][1])
Y.clamp_(bounds['Y'][0], bounds['Y'][1])
Z.clamp_(bounds['Z'][0], bounds['Z'][1])
if i % 1000 == 0: # 每1000步打印一次当前解
logger.info(f"Iteration {i}: X={X.item()}, Y={Y.item()}, Z={Z.item()}, Value={value.item()}")
final_value = function(X, Y, Z)
logger.info(f"最佳解: X={X.item()}, Y={Y.item()}")
logger.info(f"最大值: {final_value.item()}")
def run_bayes():
import numpy as np
from bayes_opt import BayesianOptimization
logger.info("\n ######################## run_bayes ######################## ")
# 定义搜索空间
pbounds = {
'X': (1, 8),
'Y': (1, 8),
'Z': (1, 8),
}
# 设置贝叶斯优化器
optimizer = BayesianOptimization(
f=objective_function,
pbounds=pbounds,
random_state=1
)
# 执行优化
optimizer.maximize(
init_points=10, # 初始随机选择的点数
n_iter=100, # 优化迭代次数
)
# 打印最佳值和对应的参数
logger.info(f"最佳解: {optimizer.max['params']}")
logger.info(f"最大值: {optimizer.max['target']}")
def run(func):
import multiprocessing as mp
p = mp.Process(target=func,args=())
p.start()
p.join()
def vis_animation():
import math
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.animation import FuncAnimation, PillowWriter
def polynomial(X,Y,Z):
return 100*np.exp(-(X - 2)**2 - (Y - 4)**2 - (Z - 2)**2)
# 生成 x 和 y 的网格
x = np.linspace(1, 8, 16)
y = np.linspace(1, 8, 16)
x, y = np.meshgrid(x, y)
# 创建图形和轴
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# 更新函数
def update(z):
ax.clear()
z_values = polynomial(x, y, z)
print(z,np.max(z_values))
ax.plot_surface(x, y, z_values, cmap='viridis')
ax.set_zlim(0, 100)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('f(X, Y, z_fixed, w)')
ax.set_title(f'z = {z:.2f}')
# 创建动画
ani = FuncAnimation(fig, update, frames=np.linspace(1, 8, 8), interval=1000)
ani.save('animation.gif', writer=PillowWriter(fps=1))
# 显示动画
plt.show()
if __name__ == '__main__':
#vis_animation()
run(dashscope)
run(moonshot)
run(qianfan)
run(sparkai)
run(gemini)
run(azure)
run(run_genetic_algorithm)
run(run_simulated_annealing)
run(run_sgd)
run(run_bayes)
测试日志
######################## dashscope ########################
---------------------------------- 第0轮 ----------------------------------
明白了,请查看第一组测试参数:
[HL_DP=2, HL_TP=2, HL_PP=4]
经过测试,上面参数对应的性能为tokens/sec:0.034,请给出新的参数配置
---------------------------------- 第1轮 ----------------------------------
了解了,根据之前的测试结果,我将调整参数以探索更优解。请尝试以下配置:
[HL_DP=4, HL_TP=2, HL_PP=2]
经过测试,上面参数对应的性能为tokens/sec:0.034,请给出新的参数配置
---------------------------------- 第2轮 ----------------------------------
看起来性能没有提升,我将继续调整参数以寻找更好的组合。请测试这一组:
[HL_DP=1, HL_TP=4, HL_PP=4]
经过测试,上面参数对应的性能为tokens/sec:0.674,请给出新的参数配置
---------------------------------- 第3轮 ----------------------------------
很好,我们发现了一组性能更好的参数。为了进一步探索可能的提升空间,接下来请尝试:
[HL_DP=2, HL_TP=4, HL_PP=2]
find best var
######################## moonshot ########################
---------------------------------- iteration 0 ----------------------------------
明白了您的要求。根据参数约束 HL_DP * HL_TP * HL_PP = 16,我们可以得出几种可能的组合。为了最大化 tokens/sec,我们可以尝试不同的组合来找到最优解。
第一组参数列表如下:
[HL_DP=4,HL_TP=2,HL_PP=2]
经过测试,上面参数对应的性能为tokens/sec:0.034,请给出新的参数配置
---------------------------------- iteration 1 ----------------------------------
根据您提供的反馈,第一组参数的性能为 tokens/sec: 0.034。由于 HL_DP * HL_TP * HL_PP 必须等于 16,我们可以尝试其他可能的组合来寻找性能更好的配置。
第二组参数列表如下:
[HL_DP=8,HL_TP=1,HL_PP=2]
经过测试,上面参数对应的性能为tokens/sec:0.000,请给出新的参数配置
---------------------------------- iteration 2 ----------------------------------
由于第二组参数的性能非常低,我们可以尝试另一种组合。考虑到 HL_DP、HL_TP 和 HL_PP 的乘积必须为 16,我们可以尝试将 HL_TP 增加,同时相应减少 HL_PP 的值。
第三组参数列表如下:
[HL_DP=4,HL_TP=4,HL_PP=1]
经过测试,上面参数对应的性能为tokens/sec:0.674,请给出新的参数配置
---------------------------------- iteration 3 ----------------------------------
根据您提供的反馈,第三组参数的性能为 tokens/sec: 0.674,这是一个比之前更好的结果。我们继续尝试不同的组合,以进一步提高性能。
第四组参数列表如下:
[HL_DP=2,HL_TP=8,HL_PP=1]
经过测试,上面参数对应的性能为tokens/sec:0.000,请给出新的参数配置
---------------------------------- iteration 4 ----------------------------------
由于第四组参数的性能为0,我们需要尝试另一种组合。考虑到之前第三组参数的性能较好,我们可以在 HL_DP=4 的基础上尝试不同的 HL_TP 和 HL_PP 的组合。
第五组参数列表如下:
[HL_DP=4,HL_TP=2,HL_PP=2]
经过测试,上面参数对应的性能为tokens/sec:0.034,请给出新的参数配置
---------------------------------- iteration 5 ----------------------------------
既然我们已经测试了几种组合,并且第三组参数的性能为0.674,这是目前最好的结果。我们可以尝试稍微调整这个组合,以期获得更好的性能。
第六组参数列表如下:
[HL_DP=2,HL_TP=4,HL_PP=2]
find best var
######################## qianfan ########################
---------------------------------- 第0轮 ----------------------------------
明白您的要求,以下是我给出的第一组参数列表,供您进行训练脚本的运行和性能测试:
[HL_DP=2,HL_TP=2,HL_PP=4]
请您使用这组参数运行训练脚本,并将得到的tokens/sec值反馈给我。我会根据反馈结果继续思考如何调整参数配置,以追求更高的性能。通过这样不断的迭代过程,我们希望能够找到近似最优解,从而让tokens/sec达到最大化。
经过测试,上面参数对应的性能为tokens/sec:0.034,请给出新的参数配置
---------------------------------- 第1轮 ----------------------------------
感谢你的反馈。根据当前的性能结果,我会尝试调整参数配置以寻求更高的`tokens/sec`值。以下是一组新的参数供你测试:
[HL_DP=4, HL_TP=2, HL_PP=2]
请使用这组参数再次运行训练脚本,并将得到的`tokens/sec`值反馈给我。我们将通过不断迭代来逼近最优解。
经过测试,上面参数对应的性能为tokens/sec:0.034,请给出新的参数配置
---------------------------------- 第2轮 ----------------------------------
由于上一组参数调整并未带来性能提升(`tokens/sec`保持为0.034),这表明在当前测试条件下,单纯改变参数的组合可能不足以实现显著的性能改善。然而,为了继续探索可能的优化空间,我们可以尝试另一种参数配置,以观察其对性能的影响。
以下是一组新的参数配置供你测试:
[HL_DP=1, HL_TP=4, HL_PP=4]
请使用这组参数运行训练脚本,并将新的`tokens/sec`值反馈给我。如果性能仍然没有提升,我们可能需要考虑其他影响因素,如数据预处理、模型架构、软件环境优化等,这些都可能对训练性能产生显著影响。
同时,如果方便的话,你可以提供更多关于训练环境和模型的信息,这样我可以给出更具体的建议。比如,GPU型号、内存大小、网络结构、批量大小等细节都可能影响训练性能。通过综合分析这些因素,我们有望找到提升`tokens/sec`的更有效方法。
经过测试,上面参数对应的性能为tokens/sec:0.674,请给出新的参数配置
---------------------------------- 第3轮 ----------------------------------
很高兴看到性能有了显著的提升(`tokens/sec`从0.034提升到0.674)!这说明我们调整的参数配置对训练速度产生了积极的影响。为了继续优化性能,我将基于当前的结果提供一组新的参数配置供你测试。
新的参数配置如下:
[HL_DP=1, HL_TP=8, HL_PP=2]
请使用这组参数再次运行训练脚本,并反馈新的`tokens/sec`值。我们将继续通过迭代不同参数组合来寻求更高的训练性能。同时,你也可以考虑其他潜在的优化手段,如进一步调整学习率、批量大小或优化模型结构,以充分挖掘硬件资源的潜力。
感谢你的持续反馈,这对我们共同找到最佳解决方案至关重要。
经过测试,上面参数对应的性能为tokens/sec:0.000,请给出新的参数配置
---------------------------------- 第4轮 ----------------------------------
很抱歉看到性能出现了大幅下降(`tokens/sec`降至0.000),这通常表明某些配置可能不兼容或存在其他问题导致训练无法有效进行。在继续调整参数之前,我们需要确保所有配置都是合理且有效的,以避免类似的情况。
考虑到之前的参数配置(HL_DP=1, HL_TP=4, HL_PP=4)曾达到0.674的`tokens/sec`,我们将回退到该配置作为起点,并进行更为谨慎的调整。以下是一组新的参数配置,旨在保持一定性能的同时探索其他可能性:
[HL_DP=2, HL_TP=4, HL_PP=2]
请使用这组参数运行训练脚本,并密切注意训练过程的任何异常或错误信息。如果再次遇到极低的`tokens/sec`值,请检查是否有硬件资源限制、软件配置错误或模型初始化问题。
此外,如果可能的话,请提供更多关于训练环境的详细信息,如GPU利用率、内存占用情况、系统日志等,这些信息有助于我们更准确地诊断问题所在。
感谢你的耐心和持续反馈,我们将共同努力找到导致性能下降的根本原因,并寻求解决方案以恢复并提升训练性能。
find best var
######################## sparkai ########################
---------------------------------- 第0轮 ----------------------------------
明白了,这是一组参数列表:
[HL_DP=0.5, HL_TP=0.5, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第1轮 ----------------------------------
非常抱歉,我的回答有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.25, HL_TP=0.25, HL_PP=0.25]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第2轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.5, HL_TP=0.25, HL_PP=0.25]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第3轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.25, HL_TP=0.5, HL_PP=0.25]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第4轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.25, HL_TP=0.25, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第5轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.5, HL_TP=0.5, HL_PP=0.25]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第6轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.25, HL_TP=0.5, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第7轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.5, HL_TP=0.25, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第8轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.5, HL_TP=0.5, HL_PP=0.25]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第9轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.25, HL_TP=0.25, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第10轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.5, HL_TP=0.25, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第11轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.25, HL_TP=0.5, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第12轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.5, HL_TP=0.5, HL_PP=0.25]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第13轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.25, HL_TP=0.5, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第14轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.5, HL_TP=0.25, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第15轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.25, HL_TP=0.5, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第16轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.5, HL_TP=0.25, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第17轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.25, HL_TP=0.5, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第18轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.5, HL_TP=0.25, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第19轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.25, HL_TP=0.5, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第20轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.5, HL_TP=0.25, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第21轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.25, HL_TP=0.5, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第22轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.5, HL_TP=0.25, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第23轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.25, HL_TP=0.5, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第24轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.5, HL_TP=0.25, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第25轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.25, HL_TP=0.5, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第26轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.5, HL_TP=0.25, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第27轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.25, HL_TP=0.5, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第28轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.5, HL_TP=0.25, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
---------------------------------- 第29轮 ----------------------------------
非常抱歉,我的回答仍然有误。根据参数约束,HL_DP乘以HL_TP乘以HL_PP等于16,因此需要重新计算参数值。
以下是一组满足约束的参数列表:
[HL_DP=0.25, HL_TP=0.5, HL_PP=0.5]
非法参数,请重新输入.
参数约束:
1.HL_DP乘以HL_TP乘以HL_PP等于16
输出格式(严格按照这个格式输出,且每次只输出一组参数,不要换行):
[HL_DP=?,HL_TP=?,HL_PP=?]
######################## gemini ########################
---------------------------------- 第0轮 ----------------------------------
明白你的要求了。
我会尽力帮助你找到近似最优解。
**第一组参数列表:**
[HL_DP=8, HL_TP=1, HL_PP=2]
请使用这组参数运行你的训练脚本,并将得到的 tokens/sec 值反馈给我。
经过测试,上面参数对应的性能为tokens/sec:0.000,请给出新的参数配置
---------------------------------- 第1轮 ----------------------------------
好的,我收到了你的反馈。tokens/sec 为 0.000 说明当前配置可能存在问题,需要进行调整。
**第二组参数列表:**
[HL_DP=4, HL_TP=2, HL_PP=2]
请使用这组参数再次运行你的训练脚本,并将得到的 tokens/sec 值反馈给我。
**解释:**
我将 HL_DP 减少了一半,将 HL_TP 增加了一倍,并将 HL_PP 保持不变。这样做的目的是尝试找到更平衡的配置,并避免出现 tokens/sec 为 0 的情况。
请继续反馈你得到的 tokens/sec 值,我会根据你的反馈继续调整参数配置,直到找到最佳配置。
经过测试,上面参数对应的性能为tokens/sec:0.034,请给出新的参数配置
---------------------------------- 第2轮 ----------------------------------
好的,我收到了你的反馈。tokens/sec 提升到了 0.034,这是一个好的开始!
**第三组参数列表:**
[HL_DP=2, HL_TP=4, HL_PP=2]
请使用这组参数再次运行你的训练脚本,并将得到的 tokens/sec 值反馈给我。
**解释:**
我继续将 HL_DP 减少了一半,并将 HL_TP 增加了一倍,保持 HL_PP 不变。
我选择这种策略的原因是,从目前的测试结果来看,tokens/sec 随着 HL_TP 的增加而增加,所以继续增加 HL_TP 看起来是提升性能的一个方向。
同时,我也降低了 HL_DP,这样可以减少模型训练时的内存占用,可能会提高训练速度。
请继续反馈你得到的 tokens/sec 值,我会根据你的反馈继续调整参数配置,直到找到最佳配置。
######################## azure ########################
---------------------------------- 第0轮 ----------------------------------
明白,请输出第一组参数列表:
[HL_DP=1,HL_TP=1,HL_PP=16]
经过测试,上面参数对应的性能为tokens/sec:0.000,请给出新的参数配置
---------------------------------- 第1轮 ----------------------------------
请输出新的参数列表:
[HL_DP=1,HL_TP=2,HL_PP=8]
经过测试,上面参数对应的性能为tokens/sec:0.000,请给出新的参数配置
---------------------------------- 第2轮 ----------------------------------
请输出新的参数列表:
[HL_DP=1,HL_TP=4,HL_PP=4]
经过测试,上面参数对应的性能为tokens/sec:0.674,请给出新的参数配置
---------------------------------- 第3轮 ----------------------------------
请输出新的参数列表:
[HL_DP=1,HL_TP=8,HL_PP=2]
经过测试,上面参数对应的性能为tokens/sec:0.000,请给出新的参数配置
---------------------------------- 第4轮 ----------------------------------
请输出新的参数列表:
[HL_DP=2,HL_TP=2,HL_PP=4]
经过测试,上面参数对应的性能为tokens/sec:0.034,请给出新的参数配置
---------------------------------- 第5轮 ----------------------------------
请输出新的参数列表:
[HL_DP=2,HL_TP=4,HL_PP=2]
find best var
######################## genetic_algorithm ########################
Generation 0
find best var
######################## run_simulated_annealing ########################
iteration: 0
....
iteration: 351
find best var
######################## run_sgd ########################
Iteration 0: X=2.5228445529937744, Y=7.7961626052856445, Z=2.6748435497283936, Value=2.6599440388963558e-05
Iteration 1000: X=2.5198171138763428, Y=7.7742085456848145, Z=2.6709437370300293, Value=3.167304384987801e-05
Iteration 2000: X=2.5161802768707275, Y=7.747806549072266, Z=2.666250467300415, Value=3.901967647834681e-05
Iteration 3000: X=2.511627674102783, Y=7.7147345542907715, Z=2.6603710651397705, Value=5.0566053687362e-05
Iteration 4000: X=2.5055480003356934, Y=7.670595645904541, Z=2.652524948120117, Value=7.121020462363958e-05
Iteration 5000: X=2.4964444637298584, Y=7.604495525360107, Z=2.640775203704834, Value=0.00011799002095358446
Iteration 6000: X=2.4782941341400146, Y=7.472714424133301, Z=2.617347478866577, Value=0.0003140216285828501
Iteration 7000: X=3.3312368392944336, Y=8.0, Z=3.7182834148406982, Value=9.985773630205586e-08
Iteration 8000: X=3.3312368392944336, Y=8.0, Z=3.7182834148406982, Value=9.985773630205586e-08
Iteration 9000: X=3.3312368392944336, Y=8.0, Z=3.7182834148406982, Value=9.985773630205586e-08
最佳解: X=3.3312368392944336, Y=8.0
最大值: 9.985773630205586e-08
######################## run_bayes ########################
| iter | target | X | Y | Z |
-------------------------------------------------------------
| 1 | 0.0143 | 3.919 | 6.042 | 1.001 |
| 2 | 0.5181 | 3.116 | 2.027 | 1.646 |
| 3 | 2.763 | 2.304 | 3.419 | 3.777 |
| 4 | 2.523e-08 | 4.772 | 3.934 | 5.797 |
| 5 | 0.002162 | 2.431 | 7.147 | 1.192 |
| 6 | 2.476e-08 | 5.693 | 3.921 | 4.911 |
| 7 | 4.561e-09 | 1.983 | 2.387 | 6.605 |
| 8 | 6.235e-20 | 7.778 | 3.194 | 5.846 |
| 9 | 7.189e-15 | 7.135 | 7.262 | 1.595 |
| 10 | 6.933e-12 | 1.273 | 2.189 | 7.147 |
| 11 | 8.693 | 1.526 | 3.719 | 3.463 |
| 12 | 5.653 | 1.314 | 4.039 | 3.55 |
| 13 | 12.09 | 1.376 | 3.487 | 3.209 |
| 14 | 35.82 | 1.482 | 3.434 | 2.662 |
| 15 | 6.084e-08 | 6.084 | 6.1 | 2.363 |
| 16 | 54.69 | 1.593 | 3.515 | 2.45 |
| 17 | 3.025e-16 | 7.688 | 5.648 | 4.295 |
| 18 | 8.933e-20 | 4.421 | 6.888 | 7.853 |
| 19 | 63.77 | 1.513 | 3.6 | 2.23 |
| 20 | 93.53 | 1.957 | 3.752 | 1.942 |
| 21 | 77.56 | 2.202 | 4.391 | 1.754 |
| 22 | 37.58 | 2.026 | 3.633 | 1.082 |
| 23 | 72.56 | 2.499 | 3.971 | 2.266 |
| 24 | 90.93 | 1.811 | 4.217 | 2.11 |
| 25 | 11.33 | 1.0 | 5.012 | 1.609 |
| 26 | 1.053e-18 | 8.0 | 1.0 | 1.0 |
| 27 | 99.91 | 2.025 | 4.015 | 1.996 |