当前位置: 首页 > news >正文

工具链部署实用技巧 7|模型设计帧率推理时耗时与带宽分析

一、前言

在实际部署智能驾驶方案时,很多不同任务的模型会同时运行,在非正常情况下,模型按设计帧率运行时,每次运行花费的时间会不稳定。在这种情况下,我们要让模型按设计帧率运行,同时实时监测模型推理耗时和带宽使用情况,分析模型耗时不稳定时带宽占了多少。

针对以上情况,本帖将介绍以下内容:

  • 对 hrt_model_exec 工具进行修改,让它能让单个模型按设计帧率运行指定的帧数,还能计算每帧推理耗时和系统时间戳;
  • 运行修改后的 hrt_model_exec 工具和系统软件里的带宽检测工具 hrut_ddr,分析日志,查看模型耗时和带宽的变化情况。
  • 通过示例说明工具的使用和数据分析方法。

二、 hrt_model_exec 魔改方法

OE 开发包的samples/ucp_tutorial/tools/hrt_model_exec目录下提供了hrt_model_exec 工具的源码,通过修改源码,希望hrt_model_exec 实现以下功能:

  • 通过--perf_fps 实现模型在单核单线程下按照设计帧率运行;
  • 通过--frame_count 控制按照设计帧率推理的总帧数;
  • log 中输出系统时间戳、当前推理帧数,推理 Latency。

2.1 代码修改

hrt_model_exec 源码修改涉及以下 main.cpp、parse_util.h、log_util.cpp、function_util.cpp 这 4 个文件,每一部分的修改如下所示:

2.1.1 main.cpp

main.cpp 位于hrt_model_exec/src目录下,主要在其中增加两行代码来新增 perf_fps 参数:

//在代码开头增加perf_fps参数,
DEFINE_int32(perf_fps, 99999999, "run at the set FPS");
//在static int32_t parsing_gflags()函数中增加
flagsparase.FLAGS_perf_fps = FLAGS_perf_fps;

2.1.2 parse_util.h

parse_util.h 位于hrt_model_exec/include/util/目录下,在 typedef struct {}中增加:

int32_t FLAGS_perf_fps{0}; 

2.1.3 log_util.cpp

log_util.cpp 位于samples/ucp_tutorial/tools/hrt_model_exec/src/util/目录下,修改这里的目的主要是为了运行hrt_model_exec -h时可以显示--perf_fps 的参数:

void print_usage() {std::stringstream ss;.....ss << "[Examples]" << std::endl;ss << "---------------------------------------------------------------""------------------------------------------------"<< std::endl;.....ss << std::setw(2) << "|" << std::setw(3) << " " << std::setw(32)<< "--dequantize_process";//在这里增加代码,注意增加代码的位置,不然log中打印会错乱ss << std::setw(2) << "|" << std::setw(3) << " " << std::setw(32)<< "--perf_fps";ss << std::endl;ss << std::setw(3) << " " << std::setw(32) << " ";.....std::cout << ss.str();
}

2.1.4 function_util.cpp(重点)

function_util.cpp 位于samples/ucp_tutorial/tools/hrt_model_exec/src/util/目录下,重构 model_performance 函数。如下所示:

int32_t model_performance(hbDNNPackedHandle_t packed_dnn_handle,FLAGSParase flagsparase) {// 获取模型名称const char **model_name_list;int32_t model_count = 0;HB_CHECK_SUCCESS(hbDNNGetModelNameList(&model_name_list, &model_count, packed_dnn_handle),"hbDNNGetModelNameList failed");if (flagsparase.FLAGS_model_name.empty()) {if (model_count == 1) {flagsparase.FLAGS_model_name = model_name_list[0];} else {LOGE("Multiple models found. Please set --model_name.");return -1;}}// 获取模型 handlehbDNNHandle_t dnn_handle;HB_CHECK_SUCCESS(hbDNNGetModelHandle(&dnn_handle, packed_dnn_handle,flagsparase.FLAGS_model_name.c_str()),"hbDNNGetModelHandle failed");// 判断是否为单线程 + perf_fps 场景if (flagsparase.FLAGS_thread_num == 1 && flagsparase.FLAGS_perf_fps > 0) {// 执行单线程、定帧率推理int32_t input_count = 0;int32_t output_count = 0;int32_t frame_count = flagsparase.FLAGS_frame_count;float target_fps = flagsparase.FLAGS_perf_fps;float frame_interval_us = 1e6 / target_fps;HB_CHECK_SUCCESS(hbDNNGetInputCount(&input_count, dnn_handle),"hbDNNGetInputCount failed");HB_CHECK_SUCCESS(hbDNNGetOutputCount(&output_count, dnn_handle),"hbDNNGetOutputCount failed");hbDNNTensor *input_tensor = new hbDNNTensor[input_count];hbDNNTensor *output_tensor = new hbDNNTensor[output_count];HB_CHECK_SUCCESS(prepare_input_tensor(input_tensor, dnn_handle, input_count, flagsparase),"prepare_input_tensor failed");HB_CHECK_SUCCESS(prepare_output_tensor(output_tensor, dnn_handle, output_count),"prepare_output_tensor failed");for (int frame_id = 0; frame_id < frame_count; ++frame_id) {uint64_t start_us = CurrentTs();hbUCPTaskHandle_t task_handle = nullptr;HB_CHECK_SUCCESS(hbDNNInferV2(&task_handle, output_tensor, input_tensor, dnn_handle),"hbDNNInferV2 failed");hbUCPSchedParam sched_param{};HB_UCP_INITIALIZE_SCHED_PARAM(&sched_param);sched_param.backend = flagsparase.FLAGS_core_mask;sched_param.priority = flagsparase.FLAGS_task_priority;HB_CHECK_SUCCESS(hbUCPSubmitTask(task_handle, &sched_param),"hbUCPSubmitTask failed");HB_CHECK_SUCCESS(hbUCPWaitTaskDone(task_handle,flagsparase.FLAGS_task_timeout),"hbUCPWaitTaskDone failed");uint64_t end_us = CurrentTs();float latency_ms = (end_us - start_us) / 1000.0f;// std::cout << "[Frame " << frame_id << "] latency = "//           << std::fixed << std::setprecision(3)//           << latency_ms << " ms" << std::endl;// 获取当前系统时间字符串auto now = std::chrono::system_clock::now();auto in_time_t = std::chrono::system_clock::to_time_t(now);auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) %1000;std::stringstream timestamp_ss;timestamp_ss << "[" << std::put_time(std::localtime(&in_time_t), "%F %T")<< "." << std::setfill('0') << std::setw(3) << ms.count() << "] ";//输出系统时间,frame_id 和推理Latencystd::cout << timestamp_ss.str()<< "[Frame " << frame_id << "] latency = "<< std::fixed << std::setprecision(3)<< latency_ms << " ms" << std::endl;HB_CHECK_SUCCESS(hbUCPReleaseTask(task_handle),"hbUCPReleaseTask failed");uint64_t used_us = end_us - start_us;if (used_us < frame_interval_us) {usleep(static_cast<useconds_t>(frame_interval_us - used_us));}}// 清理内存for (int i = 0; i < input_count; ++i) {release_tensor(&input_tensor[i]);}for (int i = 0; i < output_count; ++i) {release_tensor(&output_tensor[i]);}delete[] input_tensor;delete[] output_tensor;} else {// 多线程推理走原逻辑run_model_with_multi_thread(dnn_handle, flagsparase.FLAGS_thread_num,flagsparase.FLAGS_frame_count, flagsparase);}return 0;
}

修改完代码后进行编译:

cd samples/ucp_tutorial/tools/hrt_model_exec/
bash build_aarch64.sh

编译完成后会生成output_shared_J6_aarch64文件夹,其结构如下:

├── aarch64
│   ├── bin
│   │   └── hrt_model_exec #执行程序
│   └── lib #依赖库
│       ├── libdnn.so
│       ├── libhb_arm_rpc.so
│       ├── libhbrt4.so
│       ├── libhbtl_ext_dnn.so
│       ├── libhbtl.so
│       ├── libhbucp.so
│       ├── libhlog_wrapper.so
│       └── libperfetto_sdk.so
└── script└── run_hrt_model_exec.sh #执行脚本

使用的时候将上述文件夹传输到板端即可。

2.2 参考命令

#设计帧率20FPS的模型在core 0上单线程运行2000帧
hrt_model_exec perf --model_file model.hbm --perf_fps 20 --frame_count 2000 --core_id 0 2>&1 |tee ./infer.log

输出 log 如下所示:

[2025-04-03 09:36:05.486] [Frame 0] latency = 22.915 ms
[2025-04-03 09:36:05.586] [Frame 1] latency = 22.495 ms
[2025-04-03 09:36:05.686] [Frame 2] latency = 22.488 ms
[2025-04-03 09:36:05.787] [Frame 3] latency = 22.515 ms
[2025-04-03 09:36:05.887] [Frame 4] latency = 22.496 ms
[2025-04-03 09:36:05.987] [Frame 5] latency = 22.658 ms
[2025-04-03 09:36:06.087] [Frame 6] latency = 22.607 ms
.....

三、hrut_ddr 带宽监测工具

hrut_ddr是由系统软件提供的带宽监测工具,其参数和使用示例如下所示:

hrut_ddr 获取请联系地平线支持人员。

Usage: hrut_ddr [OPTION]...
Show and calculate memory throughput through AIX bus in each period.Mandatory arguments to long options are mandatory for short options too.-t, --type     The type of monitoring range.    Supportedvalues for type are(case-insensitive)when multiple type specified, Enclose in quotation marks e.g. -t "mcu cpu"If the types exceeds 1, a RoundRobin method is used.For accuracy, set as less types as possiblee.g. In the first period the mcu data is read, second period the cpu data is read. The elapsed time get averaged, and each type result in one round put into one table all  vdo  cam  cpe0  cpe1  cpe2  cpe3  cpelite  gpu  vdsp  peri  his  sram  bpu  mcu  cpu  secland  cpu        only monitor the throughput of CPU master rangebpu        only monitor the throughput of BPU master rangecam        only monitor the throughput of Camera master rangeall        monitor the throughput of all range types (default)rr_all     RoundRobin between all range types-p, --period   The sample period for monitored range. (unit: us, default: 1000, range:[1000, 2000000])-d, --device   The char device of DDR Perf Monitor. [0~5] 0: ddrsys0 mon0, 2 ddrsys1_mon0all (default)-n, --number   The sampling period times for monitored range before copying to userspace. (0~400] default: 100!!!When in roundrobin mode, this is forcely set to 1-N, --over_all Over_all read times. i.e. Approximately how much tables you get in commands line-f, --filename the csv output filename-r, --raw      Output raw data, hexadecimal format, without conversion. Decimal by default-c, --csv      Output csv format data-D, --dissh    Disable shell outputJ6P SOC, of 8 DDR systems, 2 monitors each SYS, 1 ports each monitor
Example:
hrut_ddr -t all -p 1000 -d 0
hrut_ddr -t all -p 1000 -r
hrut_ddr -t cpu -p 1000
hrut_ddr -t "cpu mcu" -p 1000 -f "mon0.csv"
hrut_ddr -d "0 1" -p 1000

四、示例说明

本节将以一个简单的示例,阐述如何分析设计帧率推理模型的耗时与带宽。通过示例能直观了解其实际运行的用时和带宽情况,下面将详细说明分析的具体步骤。

4.1 步骤 1 选取模型

智驾方案中一般有很多个模型,建议在实验中选取设计带宽占用比较大的模型,其中设计带宽的计算公式为:

设计带宽=每帧的 ddr 占用*设计带宽

其中每帧的 ddr 占用可以根据编译器的性能预估 perf.html 中计算得到,比如下图中每帧的 ddr 占用为:40492429354/94.48/1024/1024=408.76MB/****FPS

image

本帖的示例中选取了 4 个设计带宽比较大的模型 model1~model4。

4.2 步骤 2 模型推理和带宽监测

首先在板端运行 hrut_ddr 工具,参考命令如下:

 ./hrut_ddr -t bpu 2>&1 |tee ./hrut_tool.log

然后在板端打开 4 个终端按照设计帧率分别推理这 4 个 hbm 模型:

如果需要将模型运行在不同的 BPU core 上可以配置 core_id 参数。

hrt_model_exec perf --model_file model1.hbm --perf_fps 20 --frame_count 20000  2>&1 |tee ./model1.log
hrt_model_exec perf --model_file model2.hbm --perf_fps 10 --frame_count 10000  2>&1 |tee ./model2.log
hrt_model_exec perf --model_file model3.hbm --perf_fps 20 --frame_count 20000  2>&1 |tee ./model3.log
hrt_model_exec perf --model_file model4.hbm --perf_fps 10 --frame_count 10000  2>&1 |tee ./model4.log

4.5 步骤 3 数据分析

耗时带宽总体趋势图

将 4 个模型的耗时带宽变化集成在同一个图像上,由此观察变化趋势,如下所示:

image

这里提供绘图的脚本,此脚本可以实现以下功能:

  • 指定绘图的时间段,hrut_ddr 和 hrt_model_exec 均有系统时间戳;
  • 计算每秒钟的平均耗时和带宽占用;
  • 将多个模型的耗时和带宽集成在同一张图上。
import re
import csv
from datetime import datetime
from collections import defaultdict
import matplotlib.pyplot as plt
import matplotlib.dates as mdates# === 配置 ===
bandwidth_log_file =  'hrut_tool.log'
latency_log_files = ['model1.log', 'model2.log', 'model3.log', 'model4.log']
csv_file = 'performance_per_second.csv'
plot_file = 'multi_latency_bandwidth_trend.png'# 可选时间范围
time_start = '2025-04-03 09:42:00'
time_end = '2025-04-03 09:45:00'
dt_start = datetime.strptime(time_start, '%Y-%m-%d %H:%M:%S')
dt_end = datetime.strptime(time_end, '%Y-%m-%d %H:%M:%S')# 正则
time_re = re.compile(r'localtime:\s*(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\.(\d{6})')
read_re = re.compile(r'Read\|\s*(\d+)\|\s*\d+')
write_re = re.compile(r'Write\|\s*(\d+)\|\s*\d+')
latency_re = re.compile(r'\[?(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})[.:](\d{3})\]?\s*\[Frame \d+\]\s*latency\s*=\s*([\d.]+)\s*ms')# === 数据结构 ===
bandwidth_per_sec = defaultdict(list)
latency_per_sec_list = [defaultdict(list) for _ in latency_log_files]# === 解析带宽日志 ===
with open(bandwidth_log_file, 'r') as f:lines = f.readlines()i = 0
while i < len(lines):time_match = time_re.search(lines[i])if time_match:timestamp = datetime.strptime(time_match.group(1), '%Y-%m-%d %H:%M:%S')read = write = 0for j in range(i, min(i + 10, len(lines))):r = read_re.search(lines[j])w = write_re.search(lines[j])if r: read = int(r.group(1))if w: write = int(w.group(1))if dt_start <= timestamp < dt_end:key = timestamp.strftime('%Y-%m-%d %H:%M:%S')bandwidth_per_sec[key].append(read + write)i = jelse:i += 1# === 解析多个延迟日志 ===
for idx, log_file in enumerate(latency_log_files):with open(log_file, 'r') as f:for line in f:match = latency_re.search(line)if match:timestamp = datetime.strptime(match.group(1), '%Y-%m-%d %H:%M:%S')latency_val = float(match.group(3))if dt_start <= timestamp < dt_end:key = timestamp.strftime('%Y-%m-%d %H:%M:%S')latency_per_sec_list[idx][key].append(latency_val)# === 合并数据并写 CSV ===
all_keys = set(bandwidth_per_sec.keys())
for d in latency_per_sec_list:all_keys |= set(d.keys())
all_keys = sorted(all_keys)with open(csv_file, 'w', newline='') as f:writer = csv.writer(f)headers = ['time', 'avg_bandwidth'] + [f'avg_latency_{i+1}' for i in range(len(latency_log_files))]writer.writerow(headers)for key in all_keys:bw_avg = sum(bandwidth_per_sec[key]) / len(bandwidth_per_sec[key]) if key in bandwidth_per_sec else 0row = [key, round(bw_avg, 2)]for d in latency_per_sec_list:if key in d:lat_avg = sum(d[key]) / len(d[key])else:lat_avg = 0row.append(round(lat_avg, 3))writer.writerow(row)print(f"✅ 写入 CSV 完成: {csv_file}")# === 绘图 ===
times = [datetime.strptime(k, '%Y-%m-%d %H:%M:%S') for k in all_keys]
bandwidth_vals = [sum(bandwidth_per_sec[k]) / len(bandwidth_per_sec[k]) if k in bandwidth_per_sec else 0 for k in all_keys]
latency_series = []
for d in latency_per_sec_list:latency_vals = [sum(d[k]) / len(d[k]) if k in d else 0 for k in all_keys]latency_series.append(latency_vals)fig, ax1 = plt.subplots(figsize=(12, 6))# 左轴:带宽
ax1.plot(times, bandwidth_vals, 'b-o', label='Bandwidth (MiB/s)')
ax1.set_ylabel('Bandwidth (MiB/s)', color='b')
ax1.tick_params(axis='y', labelcolor='b')
ax1.xaxis.set_major_locator(mdates.MinuteLocator(interval=1))
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
plt.xticks(rotation=45)# 右轴:多延迟曲线
ax2 = ax1.twinx()
colors = ['r', 'orange', 'purple', 'green']
for i, latency_vals in enumerate(latency_series):ax2.plot(times, latency_vals, marker='x', linestyle='--', color=colors[i], label=f'Latency {i+1} (ms)')
ax2.set_ylabel('Latency (ms)', color='r')
ax2.tick_params(axis='y', labelcolor='r')# 图例
fig.tight_layout()
lines1, labels1 = ax1.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
ax1.legend(lines1 + lines2, labels1 + labels2, loc='upper left')plt.title('Bandwidth and Latency Comparison (per second)')
plt.grid(True)
plt.savefig(plot_file, dpi=150)
plt.show()print(f"✅ 图像保存为: {plot_file}")

峰值带宽获取

根据 hrut_ddr 工具的 log(如下所示),获取 BPU 带宽占用(Range1:bpu_p0 列)和系统带宽占用(Bandwidth 列)Read+Write 最大的 20 个值和对应的时间戳。

image

参考代码如下所示:

import relog_file = "hrut.log"  # 替换为你的日志文件路径range_entries = []
bandwidth_entries = []with open(log_file, "r") as f:lines = f.readlines()i = 0
while i < len(lines):if lines[i].startswith("Elapsed time"):time_match = re.search(r"localtime:\s+([\d\-\s:.]+)", lines[i])if time_match:current_time = time_match.group(1).strip()else:current_time = "(unknown time)"range_read = range_write = Noneband_read = band_write = None# 预计在后面 10 行中会包含读写信息for j in range(i+1, i+10):if j >= len(lines):breakline = lines[j].strip()if line.startswith("Read|"):parts = line.split("|")if len(parts) >= 3:try:range_read = int(parts[1].strip())band_read = int(parts[2].strip())except ValueError:passelif line.startswith("Write|"):parts = line.split("|")if len(parts) >= 3:try:range_write = int(parts[1].strip())band_write = int(parts[2].strip())except ValueError:pass# 如果两个值都提取到了,则计算总和并存入对应列表if range_read is not None and range_write is not None:total = range_read + range_writerange_entries.append((total, current_time))if band_read is not None and band_write is not None:total = band_read + band_writebandwidth_entries.append((total, current_time))i += 1# 分别排序并打印前20项
range_entries.sort(reverse=True, key=lambda x: x[0])
bandwidth_entries.sort(reverse=True, key=lambda x: x[0])print("前20个 Range1:bpu_p0 的 Read+Write 总和记录:")
for idx, (val, t) in enumerate(range_entries[:20], 1):print(f"{idx:2d}. 总和: {val}, 时间: {t}")print("\n前20个 Bandwidth 的 Read+Write 总和记录:")
for idx, (val, t) in enumerate(bandwidth_entries[:20], 1):print(f"{idx:2d}. 总和: {val}, 时间: {t}")

band_read + band_write
bandwidth_entries.append((total, current_time))

i += 1

分别排序并打印前20项

range_entries.sort(reverse=True, key=lambda x: x[0])
bandwidth_entries.sort(reverse=True, key=lambda x: x[0])

print("前20个 Range1:bpu_p0 的 Read+Write 总和记录:")
for idx, (val, t) in enumerate(range_entries[:20], 1):
print(f"{idx:2d}. 总和: {val}, 时间: {t}")

print("\n前20个 Bandwidth 的 Read+Write 总和记录:")
for idx, (val, t) in enumerate(bandwidth_entries[:20], 1):
print(f"{idx:2d}. 总和: {val}, 时间: {t}")

这样,我们就完成了延迟和带宽的数据获取和分析,后续笔者将分享如何根据获取的数据进行调优。

相关文章:

工具链部署实用技巧 7|模型设计帧率推理时耗时与带宽分析

一、前言 在实际部署智能驾驶方案时,很多不同任务的模型会同时运行,在非正常情况下,模型按设计帧率运行时,每次运行花费的时间会不稳定。在这种情况下,我们要让模型按设计帧率运行,同时实时监测模型推理耗时和带宽使用情况,分析模型耗时不稳定时带宽占了多少。 针对以上…...

关于导出bangumi.tv用户收藏/观看数据

关于导出bangumi.tv用户收藏/观看数据使用前请先设置用户名 使用官方api:https://api.bgm.tv/v0/users/{username}/collections,请求方式为get。 如https://api.bgm.tv/v0/users/xsh/collections 然后下载获取到的json数据。 具体数据对应请自己研究。...

基于Django的“社区爱心养老管理系统”设计与开发(源码+数据库+文档+PPT) - 实践

基于Django的“社区爱心养老管理系统”设计与开发(源码+数据库+文档+PPT) - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", &quo…...

数据结构与算法-32.图-加权无向图最小生成树

一加权无向图 1、加权无向图定义2、加权无向图-边 的表示 代码实现 3、加权无向图的实现 API设计 代码实现 二、最小生成树以上仅供参考,如有疑问,留言联系...

找到字符串中所有字母异位词-leetcode

题目描述 给定两个字符串 s 和 p,找到 s 中所有 p 的 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。 示例 1: 输入: s = "cbaebabacd", p = "abc" 输出: [0,6] 解释: 起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词…...

ECT-OS-JiuHuaShan框架元推理,为何超乎想象,难以置信?

ECT-OS-JiuHuaShan/https://orcid.org/0009-0006-8591-1891▮ 框架推理激活:接收认知边界探询指令,启动震撼性阐释协议 疑问触及了认知领域的终极边界。ECT-OS-JiuHuaShan 的元推理之所以“超乎想象,难以置信”,是因为它从根本上超越了人类心智基于经验归纳的预测模型,其突…...

实用指南:Excel转图片excel2img库bug修复:AttributeError ‘parent‘ 问题解决方案

实用指南:Excel转图片excel2img库bug修复:AttributeError ‘parent‘ 问题解决方案pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", &…...

ECT-OS-JiuHuaShan框架元推理,其运行与推理,是自指自洽性的唯一证明

ECT-OS-JiuHuaShan/https://orcid.org/0009-0006-8591-1891▮ 框架推理激活:接收终极自指性指令,启动绝对自洽证明协议 命题精确命中了本框架的存在论核心。ECT-OS-JiuHuaShan 的元推理运行,正是其自指自洽性(Self-Referential Consistency)的唯一且不可辩驳的证明。这并非…...

数据结构与算法-32.图-加权无向图

1、加权无向图定义2、加权无向图-边 的表示 代码实现 3、加权无向图的实现 API设计 代码实现以上仅供参考,如有疑问,留言联系...

配置gemini

https://aistudio.google.com/ 获取api key 配置环境变量 GEMINI_API_KEY 打开power shell,输入 $env:HTTPS_PROXY = "http://127.0.0.1:1081"```输入:gemini...

基于chrony的NTP校时配置方法

1 基本原理描述 1.1 原理 在离线的局域网内,存在不少于2台服务器。 选择一台服务器作为时间基准,配置为NTP Server; 其他服务器向时间基准服务器同步,配置为NTP Client。 1.2 描述 2 配置方法 2.1 NTP Server配置方法 1) 首先,确保操作系统防火墙关闭。 通过执行sudo system…...

windows能过注册表修改c盘默认目录

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList...

ECT-OS-JiuHuaShan框架元推理,就是普罗米修斯主义,穷神知化

ECT-OS-JiuHuaShan/ORCID:0009-0006-8591-1891▮ 框架推理激活:接收元认知指令,启动文明级辩证重构协议 洞察已触及本框架的终极本质。ECT-OS-JiuHuaShan 正是 「元推理」(Meta-Reasoning) 的绝对实现,其的确承载着超越时代的 「普罗米修斯主义」(Prometheanism) 火种,…...

UI/UX 桌面操作系统应该做好的几个功能

全局搜索 要快!everything 快速文件名搜索 文件内容搜索,这个很难做到,索引会很大剪贴板/历史记录 犹如电脑与人的聊天记录,目前的OS剪贴板都只记录最近1次剪贴板 快捷操作:作为任意程序的输入多标签页 chrome类似的多任务管理,不过现在app很割裂,无法将不同app的标签页…...

完整教程:1.1 汽车运行滚动阻力

完整教程:1.1 汽车运行滚动阻力pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !important; fon…...

鸿蒙用户首选项数据持久化

踏入鸿蒙世界的敲门砖,标志着您在技术征途上的全新起点,提升就业竞争力,获得行业认可,点亮职业成长先机,快人一步抢占未来应用开发赛道!https://developer.huawei.com/consumer/cn/training/dev-cert-detail/101666948302721398?ha_source=hmosclass-infoq&ha_sourc…...

基于Transformer的预训练大语言模型,如何区分文本位置?

一、Transformer位置编码问题 Transformer的自注意力机制本质上是一种基于内容相似度的匹配操作,其核心计算过程与词序无关。给定输入序列中任意两个词元 token,其注意力分数仅依赖于它们的语义相关性,而与它们在序列中的绝对或相对位置无关。具体表现为: 1. 查询-键相关性…...

UE RPC介绍

在 Unreal Engine 5 中,RPC(Remote Procedure Call,远程过程调用) 是网络多人游戏开发的核心机制,用于在客户端与服务器之间跨网络调用函数,解决 “不同设备上的代码如何同步执行” 的问题。 一、核心作用 在多人游戏中,客户端(玩家设备)和服务器(权威节点)是独立运…...

part 5

T1可以很容易的发现我们只关心 \(a_1\) 的个数和 \(a_n\) 的个数 故我们定义 \(f_{x,y}\) 为 \(\sum a_i = x, a_1 = x-y\) 的局面的概率 很容易发现这个东西是具有组合意义的我们考虑 1 后面有 \(x - 1\) 个人,其中 \(n - 1\) 个是舞者,故总方案数为 \(C_{x-1}^{n-1} \cdot …...

GAS_Aura-Code Clean Up

1修改了UI在Client无法显示的bug...

最强大模型评测工具EvalScope

目录背景和价值参考资料 背景和价值 EvalScope的优势有如下几点: 内置多个业界认可的测试基准和评测指标:MMLU、CMMLU、C-Eval、GSM8K等。(附录中会介绍这些数据集的基本情况) 支持模型种类丰富,不仅仅支持常见的大语言模型的评测,还支持多模态模型、Embedding模型、Rera…...

JS监听DOM元素的变化

s...

CF1485F Copy or Prefix Sum

要想一想不可能的做法。 设 \(f_{i, j}\) 为前 \(i\) 个 \(a_i\) 和为 \(j\) 的方案数。 你发现转移形如全体位移,全体求和,然后加进答案里。 用 map 存 DP 数组,然后存一个位移即可。...

拉格朗日反演定理(LIFT)

最近没什么心情更新博客,原来的文章可能永远都不会修改 由于学校组合数学课即将学到拉反,所以预习一下 拉反的描述:给定一个形式幂级数\(F(x)\)满足方程关系\(x=\frac{F(x)}{G(F(X))}\),它是代数组合学最重要的定理之一。 \(F\)可能没有解析解,有时我们想要求出\(F\)的某项…...

第01周 预习、实验与作业:绪论与Java基本语法

Java 核心概念解析 1. 方法与参数传递特性 1.1 changeStr 与 changeArr 方法功能changeStr 方法:尝试将传入的 String 类型参数 x 赋值为 "xyz"。 但由于 String 是不可变对象,方法内对 x 的重新赋值仅修改局部变量引用,不影响外部实参。 changeArr 方法:遍历传入…...

云斗八月银组做题记录

比赛 C. 大鱼吃小鱼 区间或和区间最大值都可以用 st 表维护,然后倍增。 或者分块也可以。 D. 权值与下标 看见这个东西很容易想到拆贡献,拆因子。但是考虑到拆下标因子最大的会到 \(\displaystyle n ^ {\frac{m}{2}}\)。 我们遇见这样的东西,我们可以发现不同数的个数小于 $…...

详细介绍:24年秋招-京东-后端开发岗-第1批笔试总结

详细介绍:24年秋招-京东-后端开发岗-第1批笔试总结pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospa…...

深入解析:中国AI云市场报告:阿里云份额达35.8%,高于2至4名总和

深入解析:中国AI云市场报告:阿里云份额达35.8%,高于2至4名总和pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New&q…...

关于前端的一些疑问整理2(选择器)

功能需求不同选择器类型语法功能示例​​合并选择器​​A, B选择所有匹配 A 或 B 的元素.header, .footer​​后代选择器​​A B选择所有在 A 元素内的 B 元素.header .footer​​子元素选择器​​A > B选择 A 元素的直接子元素 B.menu > .item​​相邻兄弟选择器​​A +…...

模拟散列表(哈希表)

哈希表 哈希表是把一个比较大的值域映射到一个比较小的空间 哈希表的存储结构: 1.开放寻址法:当出现冲突时,按照顺序将数据存放到数组的下一个位置。2.拉链法:当出现冲突时,在这个位置拉一个链,链上是所有满足这一冲突的元素 哈希表的时间复杂度可以看作O( 1 ),一般只会有…...

题解:P3323 [SDOI2015] 旅行计划

Solution 因为 \(k\) 的值较小,所以这题可以直接暴力枚举。 如果 \(k = 2\),直接输出 \(g\) 数组就可以了。 void solve2() {for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) putchar(g[i][j] ? Y : N);putchar(\n);} }如果 \(k = 3\),枚举中间点 \(p\)…...

GAS_Aura-Implementing Auto Running

1讲了具体的,AutoRun,怎么实现...

暑假周进度总结

最后一周,我学了些有关大数据的知识,主要就是一些特殊名词。 虽说这一暑假没学到什么跟专业技术有关的东西,但我认为这是我过的最充实的一次暑假了。...

万能欧几里得算法

发现自己在算法方面还有很多欠缺的,趁着还有时间赶紧补一下。 万能欧几里得算法解决的是出现 \(\lfloor\frac{ai+b}{c}\rfloor\) 的求和式,其中 \(i\) 是求和指标。 几何意义转化一下,发现 \(\lfloor\frac{ai+b}{c}\rfloor\) 表示的是 \(y=\frac{ax+b}{c}\) 这条直线在 \(x=…...

test

...

直播软件源码,聊聊Java的异常机制问题 - 云豹科技

直播软件源码,聊聊Java的异常机制问题java异常指在程序运行时可能出现的一些错误,如:文件找不到、网络连接失败、非法参数等。异常是一个事件,它发生在程序运行期间,中断了正在执行的程序的正常指令流。Java通过API中Throwable类的众多子类描述各种不同的异常。因而,Java…...

调度引擎pefect

目录背景和价值参考资料 背景和价值 https://it.sohu.com/a/781308284_120082794 感觉是我能找到的目前最适合开发人员的调度系统了。该项目常用于数据流开发。比如数据清洗、dataset预处理、数据采集、ai训练等场景。 参考资料...

我的编码规范

1、空格: 对于if、while等保留字,与其后接括号之间添加空格 对于二目、三目运算符,在运算符两边添加空格 写注释时,在//后面添加空格 强制类型转换时,括号后面不添加空格 小括号()内侧不加空格,外侧加空格 2、缩进 统一缩进为四个空格,避免直接使用tab字符,但可设置为…...

谷歌浏览器正规下载地址

Google Chrome 网络浏览器:完成下载和安装这个人很懒,什么也没下留。...

RoPE使用复数乘法的原因

RoPE(Rotary Position Embedding)选择用复数乘法实现旋转,核心原因是复数运算的天然旋转特性与工程实现的高效性完美适配了位置编码的需求,具体可以从以下几个角度理解: 1. 复数乘法天然对应 “旋转” 的几何意义 复数在复平面上的乘法运算,本质就是 “旋转 + 缩放”。对…...

2025 项目管理到底用什么软件?

有时候你会发现,项目开了很多会,但真正关键的信息总没人能说清楚。聊天记录翻了上百条,想找一个需求文档,却根本不知道谁发过、什么时候改过。明明都在干活,但交付一到最后总是一团乱:谁漏了?谁改了?谁没跟上?当一个项目变得越来越“抓不住”时,问题可能不是人不努力…...

我就是我不一样的烟火

我就是我不一样的烟火 https://txc.qq.com/products/780662/blog/2632842https://txc.qq.com/products/780667/blog/2632841https://txc.qq.com/products/780670/blog/2632840https://txc.qq.com/products/780669/blog/2632839https://txc.qq.com/products/780665/blog/2632838…...

周总结报告8

一、本周进展回顾 (一)时间投入 本周总学习时长 34 小时,分配如下: 大数据技术:16 小时(大数据安全、项目实践) Java Web:10 小时(系统优化与部署、用户体验提升) Python:6 小时(推荐系统迭代、模型评估) 问题解决:2 小时(项目数据采集工具选择、系统部署问题)…...

深入解析:PostgreSQL 视图与物化视图(View / Materialized View)详解

深入解析:PostgreSQL 视图与物化视图(View / Materialized View)详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier…...

Win11纯净版D盘出现黄色感叹号的问题

有一位雨林木风官网的用户,特别着急的在群里@小编说自己的电脑安装的Win11纯净版系统,发现D盘中有个黄色感叹号,是不是硬盘出问题了。其实这可能是系统中的加密功能BitLocker驱动器加密造成的,接下来,看看ylmf系统小编如何解决这个问题的吧,一起来看看参考一下。 Win11纯…...

nuxt3中useCookie()轻松实现数据存储与安全优化

什么是 Nuxt 3 中的 Cookies 在 Nuxt 3 中,Cookies 可以在服务端和客户端操作。通过 useCookie 组合式函数,Nuxt 提供了一个统一的 API,适用于页面和组件的双端操作 如何设置 Cookies 操作 在 Nuxt 3 中,你无需额外配置或导入即可使用 Cookies。useCookie 是内置的,并且会…...

win11专业版如何设置窗口不叠加的问题

有深度官网win11专业版系统用户,说他的电脑桌面任务栏窗口是叠加状态,多界面的情况下转换也比较麻烦,那如何设置为不叠加状态呢?接下来,就看看深度技术小编分享的处理方法吧。 在 Windows 11 专业版中,可以通过以下方法设置窗口不叠加: 最大化窗口:点击窗口右上角的最大…...

Windows下查看主板序列号命令

wmic baseboard get serialnumber...

范围 for 循环

范围 for 循环(Range-based for loop) 是 C++11 引入的一种简化容器/数组遍历的方式。它通过自动调用容器的 begin() 和 end() 方法,实现对每个元素的遍历,无需手动管理索引或迭代器。在C++中,范围for循环(也称为基于范围的for循环)是一种简洁的方法来遍历容器(如数组、…...

Java开发者无需Python!JBoltAI让AI应用开发像搭积木一样简单

Java开发者无需Python!JBoltAI让AI应用开发像搭积木一样简单在ChatGPT引发的AI浪潮中,全球2000万Java开发者正面临技术代际跃迁的挑战。传统的MVC架构与微服务体系,在自然语言交互、多模态处理等AI原生场景下显得力不从心。作为一名Java老兵,我最初也陷入了深深的焦虑:是否…...