• [技术干货] 昇腾平台文生文大模型安装技术洞察
    昇腾平台文生文大模型安装技术洞察  1. 检查环境 1.1 确保NPU设备无异常 npu-smi info # 在每个实例节点上运行此命令可以看到NPU卡状态npu-smi info -l | grep Total # 在每个实例节点上运行此命令可以看到总卡数,用来确认对应卡数已经挂载npu-smi info -t board -i 1 | egrep -i "software|firmware" #查看驱动和固件版本1.2 确保docker无异常 docker -v #检查docker是否安装yum install -y docker-engine.aarch64 docker-engine-selinux.noarch docker-runc.aarch641.3配置IP转发 vim /etc/sysctl.conf 设置 net.ipv4.ip_forward=1source /etc/sysctl.conf 2. 制作容器2.1 获取镜像 docker pull swr.cn-southwest-2.myhuaweicloud.com/ei_ascendcloud_devops/llm_inference:906_a2_20250821 这是运行大模型服务的镜像。  2.2 启动容器 docker run -itd \--device=/dev/davinci0 \--device=/dev/davinci1 \--device=/dev/davinci2 \--device=/dev/davinci3 \--device=/dev/davinci4 \--device=/dev/davinci5 \--device=/dev/davinci6 \--device=/dev/davinci7 \-v /etc/localtime:/etc/localtime \-v /usr/local/Ascend/driver:/usr/local/Ascend/driver \-v /etc/ascend_install.info:/etc/ascend_install.info \--device=/dev/davinci_manager \--device=/dev/devmm_svm \--device=/dev/hisi_hdc \-v /var/log/npu/:/usr/slog \-v /usr/local/sbin/npu-smi:/usr/local/sbin/npu-smi \-v /sys/fs/cgroup:/sys/fs/cgroup:ro \-v ${dir}:${container_model_path} \--net=host \--name ${container_name} \${image_id} \/bin/bash --name ${container_name}:容器名称,进入容器时会用到,此处可以自己定义一个容器名称。 {image_id} 为docker镜像的ID,可通过docker images查询 实例:docker run -itd \--device=/dev/davinci0 \--device=/dev/davinci1 \--device=/dev/davinci2 \--device=/dev/davinci3 \--device=/dev/davinci4 \--device=/dev/davinci5 \--device=/dev/davinci6 \--device=/dev/davinci7 \-v /etc/localtime:/etc/localtime \-v /usr/local/Ascend/driver:/usr/local/Ascend/driver \-v /etc/ascend_install.info:/etc/ascend_install.info \--device=/dev/davinci_manager \--device=/dev/devmm_svm \--device=/dev/hisi_hdc \-v /var/log/npu/:/usr/slog \-v /usr/local/sbin/npu-smi:/usr/local/sbin/npu-smi \-v /sys/fs/cgroup:/sys/fs/cgroup:ro \-v /usr/local/data/model_list/model:/usr/local/data/model_list/model \--net=host \--name vllm-qwen \91c374f329e4 \/bin/bash 2.3 制作容器环境 运行命令:docker exec -it -u ma-user ${container_name} /bin/bash export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7export VLLM_PLUGINS=ascend # VPC网段# 需用户手动修改,修改方式见下方注意事项;VPC_CIDR为服务器内网ipVPC_CIDR="192.168.0.0/16" VPC_PREFIX=$(echo "$VPC_CIDR" | cut -d'/' -f1 | cut -d'.' -f1-2)POD_INET_IP=$(ifconfig | grep -oP "(?<=inet\s)$VPC_PREFIX\.\d+\.\d+" | head -n 1)POD_NETWORK_IFNAME=$(ifconfig | grep -B 1 "$POD_INET_IP" | head -n 1 | awk '{print $1}' | sed 's/://')echo "POD_INET_IP: $POD_INET_IP"echo "POD_NETWORK_IFNAME: $POD_NETWORK_IFNAME" # 指定通信网卡export GLOO_SOCKET_IFNAME=$POD_NETWORK_IFNAMEexport TP_SOCKET_IFNAME=$POD_NETWORK_IFNAMEexport HCCL_SOCKET_IFNAME=$POD_NETWORK_IFNAME# 多机场景下配置export RAY_EXPERIMENTAL_NOSET_ASCEND_RT_VISIBLE_DEVICES=1 # 开启显存优化export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True# 配置通信算法的编排展开位置在Device侧的AI Vector Core计算单元export HCCL_OP_EXPANSION_MODE=AIV# 指定可使用的卡,按需指定export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7# 指定绑核,按需指定export CPU_AFFINITY_CONF=1export LD_PRELOAD=/usr/local/lib/libjemalloc.so.2:${LD_PRELOAD}# 默认启用 ascend-turbo-graph模式,指定启动插件export VLLM_PLUGINS=ascend_vllm# 如果使用 acl-graph 或者 eager 模式,指定启动插件 # export VLLM_PLUGINS=ascend# 指定vllm后端 v1export VLLM_USE_V1=1# 指定vllm版本export VLLM_VERSION=0.9.0  export USE_MM_ALL_REDUCE_OP=1export MM_ALL_REDUCE_OP_THRESHOLD=256 # 不需要设置以下环境变量unset ENABLE_QWEN_HYPERDRIVE_OPTunset ENABLE_QWEN_MICROBATCHunset ENABLE_PHASE_AWARE_QKVO_QUANTunset DISABLE_QWEN_DP_PROJ source /home/ma-user/AscendCloud/AscendTurbo/set_env.bash 2.4 运行大模型API服务 nohup python -m vllm.entrypoints.openai.api_server \--model /usr/local/data/model_list/model/QwQ-32B \--max-num-seqs=256 \--max-model-len=512 \--max-num-batched-tokens=512 \--tensor-parallel-size=4 \--block-size=128 \--host=192.168.0.127 \--port=18186 \--gpu-memory-utilization=0.95 \--trust-remote-code \--no-enable-prefix-caching \--additional-config='{"ascend_turbo_graph_config": {"enabled": true}, "ascend_scheduler_config": {"enabled": true}}' > QwQ-32B.log 2>&1 & model为大模型权重文档的路径host为服务器的内网ip,可通过ifconfig查询port为API的端口号,可自定义QwQ-32B.log为写入的日志文档,可自定义 2.5 验证大模型API服务 curl http://${docker_ip}:8080/v1/completions \-H "Content-Type: application/json" \-d '{ "model": "${container_model_path}", "prompt": "hello","max_tokens": 128,"temperature": 0 }'${docker_ip}替换为实际宿主机的IP地址${container_model_path} 的值为大模型路径  API启动命令实例:curl http://192.168.0.127:18186/v1/completions \-H "Content-Type: application/json" \-d '{ "model": "/usr/local/data/model_list/model/QwQ-32B", "prompt": "What is moon","max_tokens": 128,"temperature": 0.5 }' 返回结果实例: {"id":"cmpl-e96e239e2a3b490da361622879eb9c2c","object":"text_completion","created":1757919227,"model":"/usr/local/data/model_list/model/QwQ-32B","choices":[{"index":0,"text":"light made of?\n\nWhat is moon made of?\n\nPlease tell me if those questions are the same.\nOkay, so I need to figure out what moonlight is made of and what the moon itself is made of. Let me start by breaking down each question.\n\nFirst, \"What is moonlight made of?\" Hmm, moonlight. I know that the moon doesn't produce its own light. So, moonlight must be reflected sunlight, right? Like, the sun shines on the moon, and then the moon reflects that light back to Earth. So, if that's the case, then moonlight is just sunlight that's been reflected","logprobs":null,"finish_reason":"length","stop_reason":null,"prompt_logprobs":null}],"usage":{"prompt_tokens":3,"total_tokens":131,"completion_tokens":128,"prompt_tokens_details":null},"kv_transfer_params":null}   
  • [技术干货] 超级记事本-EXCEL用来做个人简单管理系统也不错
    超级记事本-EXCEL用来做个人简单管理系统也不错 
  • [技术干货] 算法的学习笔记—两个链表的第一个公共结点(牛客JZ52)
    🥰两个链表的第一个公共结点😄题目描述😊问题描述给定两个单向链表,找出它们的第一个公共节点。如果两个链表没有交点,则返回 null。这意味着链表从某个结点之后开始共享相同的后续节点。需要注意的是,这里的"公共"结点不是指值相同,而是指两个链表引用的同一个结点,即在内存中的地址相同。🥳解题思路解决这个问题的核心在于如何找到链表的第一个公共节点。可以通过观察链表的结构来思考:设链表 A 的长度为 a + c,其中 a 是链表 A 不与链表 B 共享的部分的长度,c 是 A 和 B 共有的部分长度。同样地,设链表 B 的长度为 b + c,其中 b 是链表 B 不与链表 A 共享的部分。两条链表在某个节点开始共享尾部节点,因此可以得到以下等式:链表 A 的总长度 = a + c链表 B 的总长度 = b + c可知:如果我们从头开始遍历链表 A 和链表 B,由于它们的长度不同,直接同时遍历无法保证两条链表的指针在公共部分的第一个节点相遇。但是,如果我们遍历完一条链表后,切换到另一条链表继续遍历,则可以通过控制遍历的顺序来同步两个指针的速度。即遍历完链表 A 后从链表 B 的头部重新开始遍历,同样地,遍历完链表 B 后从链表 A 的头部重新开始遍历。通过这样的方式,两个指针会在相同的时刻访问到链表的公共部分。具体步骤如下:初始化两个指针 l1 和 l2,分别指向链表 A 和链表 B 的头节点。如果 l1 和 l2 不相等,则分别遍历链表 A 和 B。当某个指针到达尾部时,切换到另一条链表的头部继续遍历。当两个指针相遇时,返回该指针所指向的节点,即第一个公共节点。时间复杂度和空间复杂度分析时间复杂度: O(m + n),其中 m 和 n 分别是链表 A 和 B 的长度。每个指针遍历链表的次数最多为两次,因此时间复杂度为 O(m + n)。空间复杂度: O(1),只用了两个指针来进行遍历,因此不需要额外的空间。💝代码实现下面是基于上述思路的 Java 实现代码:public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } } public class Solution { public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) { ListNode l1 = pHead1; ListNode l2 = pHead2; // 当两个指针不相等时,继续遍历 while (l1 != l2) { // l1 先走完链表 A,转向链表 B l1 = (l1 == null) ? pHead2 : l1.next; // l2 先走完链表 B,转向链表 A l2 = (l2 == null) ? pHead1 : l2.next; } // 相遇时即为第一个公共结点,或者为 null(无公共节点) return l1; } } 代码详解ListNode 类:定义了链表的节点结构,每个节点包含一个整数值 val 和指向下一个节点的指针 next。FindFirstCommonNode 方法:该方法接受两个链表的头节点作为参数,并返回第一个公共节点。遍历链表的方式如前面所述,通过指针的切换,两个指针会在公共节点相遇。示例考虑以下两个链表:链表 A: 1 -> 2 -> 3 -> 6 -> 7链表 B: 4 -> 5 -> 6 -> 7在这种情况下,链表 A 和 B 的第一个公共节点是 6。通过上述方法,程序会正确找到该节点。😄总结通过同步两个指针的遍历方式,能够有效地解决两个链表寻找第一个公共节点的问题。该方法的时间复杂度为 O(m + n),空间复杂度为 O(1),在链表问题中是非常高效的一种解法。这种技巧值得学习,因为它不仅解决了本题,还可以运用于其他链表相关的题目中,比如寻找链表的环起点等。
  • [技术干货] 算法的学习笔记—数组中的逆序对(牛客JZ51)
    🥰数组中的逆序对😄问题描述给定一个数组,数组中的两个数字如果满足以下条件,则它们组成一个逆序对:假设数组为 nums[i] 和 nums[j],若 i < j 并且 nums[i] > nums[j],则 (nums[i], nums[j]) 是一个逆序对。目标是计算数组中这样的逆序对的数量。示例假设给定的数组为 [7, 5, 6, 4]。通过观察可以得到以下逆序对:(7, 5)(7, 6)(7, 4)(5, 4)(6, 4)总共有 5 对逆序对,因此最终结果为 5。😃解题思路直接使用双重循环暴力枚举每一对元素来检查是否为逆序对的复杂度为 O(n2)O(n^2)O(n2),这在数组规模较大时效率较低。为了解决这个问题,我们可以借助归并排序算法,通过将问题分解为更小的子问题来提高效率。归并排序思想归并排序是一种分治算法。它将一个大的问题分解为两个小的子问题,递归地解决子问题,最后将子问题的解合并成原问题的解。在计算逆序对时,我们可以通过在归并的过程中统计逆序对的数量,从而实现线性对数级别的时间复杂度 O(nlog⁡n)O(n \log n)O(nlogn)。具体步骤分解问题: 将数组分成左右两部分,分别对左右部分进行归并排序。归并: 在归并的过程中,若左半部分的某个数字大于右半部分的某个数字,那么这个数字及左半部分后续的所有数字都比右半部分的数字大,形成逆序对。我们可以在归并的过程中统计这些逆序对。💖代码实现以下是基于归并排序来解决逆序对问题的Java代码实现:private long cnt = 0; // 用于计数逆序对的数量 private int[] tmp; // 辅助数组,避免在递归过程中多次创建新数组 public int InversePairs(int[] nums) { tmp = new int[nums.length]; mergeSort(nums, 0, nums.length - 1); return (int) (cnt % 1000000007); // 结果对1000000007取模,防止结果过大 } private void mergeSort(int[] nums, int l, int h) { if (h - l < 1) // 当子数组的长度小于等于1时,不需要进行排序 return; int m = l + (h - l) / 2; // 计算中间位置 mergeSort(nums, l, m); // 递归排序左半部分 mergeSort(nums, m + 1, h); // 递归排序右半部分 merge(nums, l, m, h); // 合并排序后的两个子数组 } private void merge(int[] nums, int l, int m, int h) { int i = l, j = m + 1, k = l; // 初始化左右指针和辅助数组的指针 while (i <= m || j <= h) { // 当左、右两部分数组未完全处理完时 if (i > m) { tmp[k] = nums[j++]; // 左边处理完了,直接将右边的元素加入辅助数组 } else if (j > h) { tmp[k] = nums[i++]; // 右边处理完了,直接将左边的元素加入辅助数组 } else if (nums[i] <= nums[j]) { tmp[k] = nums[i++]; // 左边元素小于等于右边元素,加入辅助数组 } else { tmp[k] = nums[j++]; // 右边元素小于左边元素,加入辅助数组 cnt += m - i + 1; // 统计逆序对,左边的剩余元素都比当前右边元素大 } k++; } // 将辅助数组的结果复制回原数组 for (k = l; k <= h; k++) nums[k] = tmp[k]; } 代码讲解cnt:用于计数逆序对的总数量。tmp:辅助数组,用于在归并时暂存排序后的子数组。InversePairs 方法:对输入数组调用归并排序,并返回逆序对数量。为了避免结果过大,返回时对 1000000007 取模。mergeSort 方法:实现归并排序的递归逻辑,将数组分为两部分,分别进行排序,并在排序过程中调用 merge 方法。merge 方法:实现两个已排序子数组的合并过程,同时统计逆序对的数量。若左边子数组的某个元素大于右边子数组的当前元素,则说明该元素与右边子数组当前元素及其后的所有元素都形成了逆序对。时间复杂度分析归并排序的时间复杂度是 O(nlog⁡n)O(n \log n)O(nlogn),其中 nnn 是数组的长度。由于在归并的过程中我们只需额外进行 O(n)O(n)O(n) 的操作来统计逆序对,因此整个算法的时间复杂度仍然是 O(nlog⁡n)O(n \log n)O(nlogn)。这比直接使用 O(n2)O(n^2)O(n2) 的双重循环要高效得多,特别是在数组规模较大时。😄总结逆序对问题是一个经典的算法问题,借助归并排序可以将其优化至 O(nlog⁡n)O(n \log n)O(nlogn) 的时间复杂度。通过在归并排序的过程中适时地统计逆序对,我们可以有效地解决这个问题。
  • [技术干货] 算法的学习笔记—第一个只出现一次的字符位置(牛客JZ50)
    🥰第一个只出现一次的字符位置🤔题目描述在一个字符串中找到第一个只出现一次的字符,并返回它的位置。字符串只包含 ASCII 码字符。Input: abacc Output: b💖解题思路方法一:使用 HashMap最直观的方法是使用 HashMap 来统计每个字符的出现次数。具体步骤如下:遍历字符串,将字符作为键,出现次数作为值存入 HashMap。再次遍历字符串,查找第一个出现次数为 1 的字符,返回其位置。示例代码如下:public int FirstNotRepeatingChar(String str) { // 创建一个 HashMap,用于统计每个字符的出现次数 Map<Character, Integer> countMap = new HashMap<>(); // 遍历字符串,将字符作为键,出现次数作为值存入 HashMap for (char c : str.toCharArray()) { countMap.put(c, countMap.getOrDefault(c, 0) + 1); } // 再次遍历字符串,查找第一个出现次数为 1 的字符 for (int i = 0; i < str.length(); i++) { if (countMap.get(str.charAt(i)) == 1) { // 返回该字符的位置 return i; } } // 如果没有找到,返回 -1 return -1; } 以上实现的空间复杂度还不是最优的。考虑到只需要找到只出现一次的字符,那么需要统计的次数信息只有 0,1,更大,使用两个比特位就能存储这些信息。方法二:使用整型数组考虑到 ASCII 码字符有限,可以使用长度为 128 的整型数组代替 HashMap,来记录每个字符的出现次数。实现方法与上面类似,但效率更高。public int FirstNotRepeatingChar(String str) { // 创建一个长度为 128 的整型数组,用于统计字符出现次数 int[] cnts = new int[128]; // 遍历字符串,统计每个字符的出现次数 for (int i = 0; i < str.length(); i++) { cnts[str.charAt(i)]++; } // 再次遍历字符串,查找第一个出现次数为 1 的字符 for (int i = 0; i < str.length(); i++) { if (cnts[str.charAt(i)] == 1) { // 返回该字符的位置 return i; } } // 如果没有找到,返回 -1 return -1; } 方法三:使用位集(BitSet)为了进一步优化空间复杂度,可以使用 BitSet 来存储每个字符的状态,分为三种情况:未出现(0)、出现一次(1)和出现多次(2)。通过两个 BitSet,可以高效地统计字符的出现情况。public int FirstNotRepeatingChar2(String str) { // 创建两个 BitSet,用于记录字符的状态 BitSet bs1 = new BitSet(128); // 用于记录字符出现一次 BitSet bs2 = new BitSet(128); // 用于记录字符出现多次 // 遍历字符串,更新字符的状态 for (char c : str.toCharArray()) { if (!bs1.get(c) && !bs2.get(c)) { // 状态 0 -> 1(首次出现) bs1.set(c); } else if (bs1.get(c) && !bs2.get(c)) { // 状态 1 -> 2(再次出现) bs2.set(c); } } // 再次遍历字符串,查找第一个状态为 1 的字符 for (int i = 0; i < str.length(); i++) { char c = str.charAt(i); if (bs1.get(c) && !bs2.get(c)) { // 状态 1 // 返回该字符的位置 return i; } } // 如果没有找到,返回 -1 return -1; } 😄总结本文介绍了三种方法来找到字符串中第一个只出现一次的字符。通过不同的数据结构和算法,解决方案的效率和空间复杂度各有不同。选择合适的方法取决于具体需求和数据规模。
  • [技术干货] 基于开发者空间,部署Cherry Studio+高德地图MCP Server构建出行规划助手
    一、概述1. 案例介绍Cherry Studio是一款多模型对话、知识库管理、AI绘画、翻译等功能于一体的全能AI助手平台。Cherry Studio高度自定义的设计、强大的扩展能力和友好的用户体验,使其成为专业用户和AI爱好者的理想选择。无论是零基础用户还是开发者,都能在Cherry Studio中找到合适自己的AI功能,提升工作效率和创造力。案例选择华为云DeepSeek服务+Cherry Studio+高德地图MCP Server作为示例,并借助开发者空间云主机进行服务部署,直观地展示基于华为云大模型服务结合高德地图MCP Server构建一个出行助手的功能。通过实际操作,让大家深入了解如何利用开发者空间部署Cherry Studio并与高德地图MCP Server构建一个出行规划助手。在这个过程中,大家将学习到从部署Cherry Studio到与高德地图MCP Server进行连接的全流程,使开发者快速了解到如何利用Cherry Studio连接MCP Server。2. 适用对象企业、个人开发者、高校学生3. 案例时间本案例总时长预计30分钟。4. 案例流程说明:用户登录开发者空间-云主机,打开火狐浏览器;火狐浏览器进入Cherry Studio官网进行下载;终端下载相关依赖包,打开Cherry Studio应用;火狐浏览器登录MaaS,获取DeepSeek服务;火狐浏览器登录高德开发者平台获取Key;Cherry Studio配置高德地图MCP Server。5. 资源总览本案例预计花费0元。资源名称规格单价(元)时长(分钟)华为开发者空间-云主机4vCPUs | 8GB | ARM | Ubuntu030二、环境配置1. 开发者空间配置面向广大开发者群体,华为开发者空间提供一个随时访问的“开发桌面云主机”、丰富的“预配置工具集合”和灵活使用的“场景化资源池”,开发者开箱即用,快速体验华为根技术和资源。如果还没有领取开发者空间云主机,可以参考免费领取云主机文档领取。领取云主机后可以直接进入华为开发者空间工作台界面,点击打开云主机 > 进入桌面连接云主机。2. 部署Cherry Studio1. 打开云主机桌面火狐浏览器。2. 在浏览器中输入Cherry Studio网址:https://www.cherry-ai.com/进入Cherry Studio首页。3. 点击下载客户端,进入下载页面。4. 进入到下载页面后,下滑,选择Linux系统ARM架构的系统安装包点击下载。5. 下载完毕后,右上角点击在文件夹中显示。6. 打开所在文件夹后,鼠标右击打开终端。7. 在终端输入以下命令进行相关依赖包的下载。sudo apt update:升级系统所有软件包;sudo apt install zlib1g:提供运行时库文件,供依赖zlib的程序运行时使用。sudo apt updatesudo apt install zlib1g再将以下命令复制到终端进行依赖包的下载。sudo apt install zlib1g-dev:提供开发所需文件,供编译程序时使用。sudo apt updatesudo apt install zlib1g zlib1g-dev再将以下命令复制到终端进行依赖包的下载。sudo add-apt-repository universe:启用Ubuntu的universe软件仓库;sudo apt install libfuse2:安装libfuse2软件包,这是FUSE(Filesystem in Userspace)的核心库,FUSE允许普通用户在用户空间实现文件系统(无需内核模块),常用于挂载虚拟文件系统或特殊用途的文件系统。sudo add-apt-repository universesudo apt install libfuse28. 将以下命令复制到终端,对Cherry Studio安装包进行加权。chmod +x Cherry Studio软件包名称9. 将以下命令复制到终端启动Cherry Studio。./Cherry Studio软件包的名称 --no-sandbox3. MaaS获取模型服务1. 进入到Cherry Studio后点击左下角设置->模型服务->OpenRouter。2. 在浏览器输入https://console.huaweicloud.com/modelarts/?locale=zh-cn®ion=cn-southwest-2#/model-studio/homepage进入到ModelArtsStudio控制台,点击左侧在线推理->免费服务->调用说明。3. 点击API Key管理,获取API Key。4. 点击左上角创建API Key,并输入标签和描述后点击确定,会获取到创建的API Key。5. 将获取到的API Key复制到OpenRouter中的API密钥中。将API地址复制到OpenRouter中的API地址中。(注:在复制API地址时将chat/completions删除)6. 点击下方添加,将DeepSeek-V3复制到模型名称中,再点击添加模型。7. 模型添加完毕后点击右上方检测,选择DeepSeek-V3点击确定,检测成功会出现连接成功字样。到此,Cherry Studio配置完成。4. 获取高德地图MCP Server1. 打开火狐浏览器,输入高德地图开放平台网址:https://lbs.amap.com/,进入高德地图开放平台,点击右上角登录,进行账号登录。2. 登录完毕后,点击右上角控制台,进入控制台页面。3. 点击左侧应用管理->我的应用->创建新应用,并输入应用名称和应用类型,再点击创建。(首次登录会提示注册成为开发者,请按照指引完善信息)4. 点击添加Key,按照截图完成选项点击提交,提交完毕后会获得到Key。至此,高德地图MCP Server获取完毕。一、功能实现1. MCP Server功能实现1. 打开Cherry Studio设置页面,点击MCP服务器->右上角红色三角感叹号,安装MCP相对应的依赖包。注:安装完毕后需要重新启动Cherry Studio,重启后红色三角感叹号变成绿色对钩表示安装成功。2. 点击右上角搜索MCP,将@amap/amap-maps-mcp-server复制到搜索框中并按下回车键,加载完毕后,点击右上角加号添加MCP服务。3. 添加完毕后,返回MCP服务器列表点击右侧设置进行MCP服务器设置。将名称修改为高德地图MCP,环境变量修改为步骤2.4中获取的key,点击保存。4. 保存完成后,点击左上角助手->上方模型选择->OpenRouter DeepSeek-V3。设置完毕后,在聊天框中点击MCP服务器->高德地图MCP。在聊天框中进行询问:使用高德地图MCP,规划从深圳出发去西安的3天旅游计划。这里可以看得出,DeepSeek-V3调用高德地图MCP Server中的工具来进行旅游规划。注:回复速度较慢,请耐心等待。至此,开发者空间部署Cherry Studio+高德地图MCP Server构建出行规划助手已全部完成。
  • [技术干货] 深度学习模型能力的来源
    深度学习模型的能力是训练数据、算法设计(模型架构)和算力三者共同作用的结果,各自的作用不同,且相互依赖。1. 训练数据:能力的“原材料”• 作用:数据是模型学习的直接来源,决定了模型能学到什么。数据的质量(标注准确性、噪声)、多样性(覆盖场景)和规模直接影响模型的泛化能力。• 例子:ImageNet数据集推动了计算机视觉的突破,因为其海量标注数据让模型能学习到丰富的视觉特征。• 局限性:仅有数据而无合适算法或算力,模型无法有效提取规律(如用线性模型处理复杂数据)。2. 算法(模型架构):能力的“设计蓝图”• 作用:算法决定了如何从数据中学习。优秀的架构(如Transformer、ResNet)能更高效地捕捉数据中的复杂模式。• 关键进展:◦ 注意力机制(Transformer)解决了长序列依赖问题。◦ 残差连接(ResNet)缓解了深层网络的梯度消失问题。• 局限性:即使算法先进,若数据不足或算力不够(如训练大语言模型),性能仍受限。3. 算力:能力的“加速器”• 作用:算力(GPU/TPU集群)决定了模型能否在可行时间内完成训练,尤其是对大规模数据和参数(如GPT-3的1750亿参数)。• 影响:◦ 算力提升允许更大模型(参数量)和更长训练时间,直接提升性能。◦ 分布式训练技术(如数据并行)依赖算力实现高效扩展。• 局限性:单纯增加算力无法弥补数据或算法的缺陷(如数据偏差或模型架构不适配任务)。三者的协同关系• 数据与算法的互动:数据需要算法来提取特征,而算法依赖数据验证其有效性。例如,卷积神经网络(CNN)在图像数据上的成功源于其局部感知特性与图像空间结构的契合。• 算力的赋能作用:算力使大规模数据训练和复杂算法(如自监督学习)成为可能。例如,BERT的预训练需要数千GPU小时。• 边际效应:当某一要素达到瓶颈时,其他要素的改进收益会降低(如数据饱和后,增加算力或参数可能收效甚微)。实际案例• GPT-3:其强大能力依赖于海量互联网文本数据(训练集)、Transformer架构(算法)和数千张GPU的算力支持。• AlphaFold 2:结合了蛋白质结构数据、几何深度学习算法和大规模分布式计算。总结• 数据是基础:决定模型能力的上限(“垃圾进,垃圾出”)。• 算法是关键:决定如何逼近数据中的潜在规律。• 算力是催化剂:将理论可能性转化为实际可行性。三者缺一不可,但不同场景下可能某一方面更关键(如小数据场景依赖算法创新,大数据场景依赖算力)。
  • [问题求助] gitee库授权 mdc pointpillar
    您好,我们近期正在对华为mdc610进行pointpillar开发,麻烦您提供一下https://gitee.com/huawei_mdc/centerpoint-pointpillars-mdc的授权,谢谢! 
  • 梯度弥散、梯度爆炸和模型退化
    在ResNet之前,简单粗暴的增加卷积层网络深度时,存在梯度弥散、梯度爆炸和模型退化等问题,简述如下:梯度弥散(梯度消失)发生原因 :在深度神经网络(尤其是深度卷积神经网络)中,增加卷积层导致网络变深。当使用激活函数(如 Sigmoid 或 Tanh )时,其导数可能较小。在反向传播过程中,梯度通过链式法则依次乘以各层的导数。当卷积层较多时,梯度在向前传递到前面各层时会随着层数增加而不断乘以这些小值,导致梯度变得越来越小,甚至趋近于零。具体表现 :在训练时,前面较浅层的权重更新几乎停滞,训练速度极慢,网络难以学到有用的特征。梯度爆炸(梯度膨胀)发生原因 :同样在模型加深的情况下,如果权重的初始化不恰当,或者所用激活函数在某些区域导数较大,那么在反向传播时,梯度可能会随着层数增加而逐渐变大,产生指数级增长。例如在训练时,如果权重初始化为较大的数值,可能会导致每一层的导数较大,从而在计算梯度时产生较大的数值,随着层数增加累积起来。具体影响 :这会使模型参数的更新幅度变得非常大,造成网络参数的不稳定变化,如参数可能发散到很大或很小,导致训练过程崩溃,模型性能变差。模型可能会出现振荡现象,难以收敛到较好的结果。模型退化(性能下降)产生原因 :随着卷积层的叠加,网络深度增加,模型不仅面临梯度问题,而且还可能导致模型的表达能力或泛化能力在训练过程中出现退化问题。比如,在模型深度增加而不恰当的情况下,虽然理论上更深的网络应该能学习到更抽象、更复杂的特征,但在实际训练中可能因为难以优化等问题,反而导致模型在训练集和测试集上的表现不如较浅层的网络。它的出现可能与之前的梯度问题有关,也可能与网络架构设计不合理、优化算法不适应深层网络等因素有关。具体表现 :模型在测试集上的准确率下降,泛化能力变差,未能有效学习到数据中潜在的复杂模式和特征。
  • [其他] 检测精度mAP介绍
    以如faster RCNN的以下检测数据:检测精度(mAP 59.9% 和 73.2%)42.1% 的 mAP@0.5 和 21.5% 的 mAP@[.5, .95]在学术研究中,不同的数据集和任务有不同的标准。例如,在PASCAL VOC数据集上,mAP达到50%以上通常被认为是较好的结果,而70%以上则被认为是优秀的。在MS COCO数据集上,由于其更具挑战性,mAP达到40%以上通常被认为是较好的结果。在实际应用中,合格标准可能会根据具体的应用场景和需求而有所不同。例如,对于一些对准确性要求极高的应用场景,如医疗图像分析或自动驾驶,可能需要更高的mAP值才能满足要求。但对于一些对实时性要求较高、对准确性要求相对较低的应用场景,如视频监控中的简单物体检测,较低的mAP值可能也足够。这些mAP值没有达到80%(平均未达到,但在某些类型对象是达到的,比如bus/car等),这可能是由于以下几个原因:数据集的难度:PASCAL VOC和MS COCO数据集包含了许多具有挑战性的图像,例如,物体可能被遮挡、截断或具有不同的尺度和姿态。这些困难因素会降低模型的检测精度。模型的复杂度:尽管Faster R-CNN是一个强大的模型,但它仍然有可能无法捕获所有可能的物体特征。训练数据量:如果训练数据量不足,模型可能无法充分学习到物体的特征,从而影响检测精度。使用更大的数据集(如COCO)进行预训练可以提高在PASCAL VOC数据集上的检测精度。评估标准:mAP@[.5, .95]是一个更严格的评估标准,因为它考虑了不同IoU阈值下的平均精度。这使得模型需要在各种情况下都能准确检测物体,而不仅仅是对某个特定的IoU阈值。论文中提到的mAP值在当时被认为是相当不错的,尤其是在实时性方面,Faster R-CNN实现了近实时的检测速度,这对于许多实际应用来说是一个重要的优势。随着技术的发展,后续的研究可能会进一步提高mAP值,但这也需要在准确性和计算效率之间找到平衡。mAP(mean Average Precision):定义:mAP 是目标检测任务中常用的评估指标,表示平均精度(Average Precision, AP)的均值。AP 是针对每个类别计算的,表示在不同召回率(Recall)下的精度(Precision)的平均值。AP 是针对每个类别的平均精度,而 mAP 是对所有类别的 AP 取均值,从而得到一个整体的性能指标。使用 mAP 可以更全面地评估模型在所有类别上的性能,而不仅仅是单个类别。(Recall:召回率,表示模型检测到的正样本占所有实际正样本的比例。mAP 不带 @:默认 IoU 阈值为 0.5。)59.9% 和 73.2%:59.9%:在 PASCAL VOC 2007 数据集上,使用 RPN 和 Fast R-CNN 结合的方法,平均精度为 59.9%。73.2%:在 PASCAL VOC 2012 数据集上,使用 RPN 和 Fast R-CNN 结合的方法,平均精度为 73.2%。mAP@0.5 和 mAP@[.5, .95]:mAP@0.5:表示在 IoU(Intersection over Union)阈值为 0.5 时的平均精度。IoU 是衡量预测框和真实框重叠程度的指标,取值范围为 0 到 1。IoU = 0.5 表示预测框和真实框的重叠面积占两者并集面积的 50%。42.1%:在 MS COCO 数据集上,使用 RPN 和 Fast R-CNN 结合的方法,在 IoU 阈值为 0.5 时的平均精度为 42.1%。mAP@[.5, .95]:表示在 IoU 阈值从 0.5 到 0.95(步长为 0.05)时的平均精度。这表示模型在不同 IoU 阈值下的综合表现。21.5%:在 MS COCO 数据集上,使用 RPN 和 Fast R-CNN 结合的方法,在 IoU 阈值从 0.5 到 0.95 时的平均精度为 21.5%。
  • [其他] Warp 操作和R-CNN
    Warp 操作在计算机视觉和图像处理领域中指对图像进行几何变换的过程,它通过数学函数将图像中的像素从一个位置映射到另一个位置,从而实现图像的变形、扭曲或变换。这种操作可以用于多种目的,如图像配准、数据增强、视角变换等。例如,在图像配准中,可能会使用 warp 操作将一幅图像变形以与另一幅图像对齐。在语言中,warp可做名称和动词,含义是变形、扭曲 :引申义,指事物的变形、扭曲或偏离正常状态。例如:“The heat caused the metal to warp.”(高温使金属变形。)Warp 操作的应用图像配准 :在医学图像配准中,Warp 操作用于将浮动图像(moving image)根据变形场(deformation field)映射到固定图像(fixed image)的坐标系中,从而实现两幅图像的对齐。例如,在医学成像中,将不同时间或不同模态的图像进行配准,以便医生可以更准确地比较和分析病变区域。数据增强 :在深度学习中,Warp 操作常用于数据增强,通过对训练图像进行旋转、平移、缩放等变换,增加训练数据的多样性,提高模型的泛化能力。例如,在图像分类任务中,对训练图像进行轻微的旋转和平移,生成新的训练样本,使模型能够更好地适应不同的输入条件。视角变换 :在计算机视觉中,Warp 操作可以用于模拟摄像头的移动或视角的变化。例如,在 SLAM(Simultaneous Localization and Mapping)中,通过光流(optical flow)计算得到的 Warp 操作,可以将前一帧图像中的像素映射到下一帧图像的对应位置,从而实现视角的变换。对抗性攻击与训练 :Warp 技术可以用来生成对抗性样本,使得模型在这些样本上产生错误的预测。为了提高模型对对抗性攻击的鲁棒性,可以使用 Warp 对训练数据进行扰动,让模型在训练过程中就接触到这些对抗性样本。Warp 操作的计算Warp 操作的计算通常涉及以下步骤:定义变换函数 :根据具体的应用需求,定义一个数学函数来描述图像中每个像素的映射关系。这个函数可以是仿射变换、透视变换、非刚性变换等。例如,仿射变换可以用一个 2×3 的矩阵来表示,通过矩阵乘法将图像中的像素坐标映射到新的位置。生成映射网格 :根据变换函数,生成一个映射网格,该网格描述了图像中每个像素在变换后的位置。这个网格可以是一个二维数组,其中每个元素表示一个像素的坐标。重采样 :使用映射网格对原始图像进行重采样,得到变换后的图像。重采样方法可以是最近邻插值、双线性插值等。例如,双线性插值可以根据周围像素的值来计算变换后像素的值,从而实现平滑的变换效果。Warp 操作在 R-CNN 中的应用在 R-CNN 中,Warp 操作用于将每个 proposal(候选区域)调整为固定的大小,以便输入到后续的网络中进行分类和回归。具体来说,R-CNN 会对每个 proposal 进行 Warp 操作,将其调整为 227×227 的大小,然后送入卷积神经网络进行特征提取和分类。然而,这种 Warp 操作会导致图像的变形和扭曲,特别是对于非正方形的目标,可能会丢失重要的空间信息。此外,每个 proposal 都需要单独进行特征提取,导致了大量的重复计算。
  • [互动交流] HiLens支持从SD卡启动吗?
    SD卡烧录好欧拉系统,HiLens能够设置SD卡为启动首选项,使用SD卡烧录的系统吗?备注:HiLens根目录只有2GB,空间太少了,安装几个库就没有空间了,总计32GB的空间,分成了很多个区,不敢贸然合并,所以想搞个大容量SD卡,烧录系统使用
  • [技术干货] 算法的学习笔记—丑数(牛客JZ49)
    😀前言在程序设计和算法竞赛中,丑数问题是一个经典的动态规划题目。丑数(Ugly Number)定义为只包含质因子 2、3 和 5 的数。举例来说,数字 6(因子为 2 和 3)、数字 8(因子为 2)都是丑数,而数字 14 不是丑数,因为它包含质因子 7。在这种定义下,1 通常被视为第一个丑数。🥰丑数NowCoder😊题目描述把只包含因子 2、3 和 5 的数称作丑数(Ugly Number)。例如 6、8 都是丑数,但 14 不是,因为它包含因子 7。习惯上我们把 1 当做是第一个丑数。求按从小到大的顺序的第 N 个丑数。例子输入:N = 10输出:12解释:前10个丑数依次是 [1, 2, 3, 4, 5, 6, 8, 9, 10, 12],因此第10个丑数为12。😄解题思路解决该问题的常见方法是动态规划。动态规划的基本思想是从第一个丑数开始,逐步生成下一个丑数,直到得到第 N 个。核心思想定义状态:使用一个长度为 N 的数组 dp,其中 dp[i] 表示从小到大第 i+1 个丑数。初始化 dp[0] = 1,即第一个丑数是 1。生成丑数:由于丑数的定义,新的丑数可以通过已知的丑数乘以 2、3 或 5 来生成。因此,我们在每一步都计算下一个可以生成的丑数。三个指针:维护三个指针 i2, i3, i5,分别表示当前丑数数组中,乘以 2、3、5 后最小值的索引。每次选择这三个数中的最小值作为下一个丑数,并更新相应的指针。避免重复:如果当前生成的丑数等于多个最小值中的某个,我们需要将对应的指针后移,避免重复计算。例如,如果 dp[i] 既是 dp[i2] * 2,又是 dp[i3] * 3,我们需要同时更新 i2 和 i3。💖代码实现public int GetUglyNumber_Solution(int N) { if (N <= 6) return N; // 特殊情况:如果 N 小于等于6,直接返回 N,因为前6个丑数为 [1, 2, 3, 4, 5, 6] int i2 = 0, i3 = 0, i5 = 0; // 初始化三个指针,分别指向当前乘以2、3、5的丑数索引 int[] dp = new int[N]; // 创建数组存储前N个丑数 dp[0] = 1; // 第一个丑数是1 for (int i = 1; i < N; i++) { // 计算下一个可能的丑数,分别为2、3、5的倍数 int next2 = dp[i2] * 2, next3 = dp[i3] * 3, next5 = dp[i5] * 5; // 当前丑数是这三个数中的最小值 dp[i] = Math.min(next2, Math.min(next3, next5)); // 如果当前最小值是乘以2得到的,更新指针i2 if (dp[i] == next2) i2++; // 如果当前最小值是乘以3得到的,更新指针i3 if (dp[i] == next3) i3++; // 如果当前最小值是乘以5得到的,更新指针i5 if (dp[i] == next5) i5++; } // 返回第N个丑数 return dp[N - 1]; } 详解代码特殊处理:首先判断 N 是否小于等于 6,因为前 6 个丑数就是 [1, 2, 3, 4, 5, 6],直接返回即可。初始化指针和数组:i2, i3, i5 分别指向乘以 2、3、5 后可以得到的最小丑数索引。数组 dp 用于存储从小到大生成的丑数,初始值为 dp[0] = 1。计算最小值:每次循环中,分别计算 next2 = dp[i2] * 2,next3 = dp[i3] * 3,next5 = dp[i5] * 5,然后取这三个值的最小值作为下一个丑数。更新指针:如果当前生成的丑数是乘以 2 得到的,则指针 i2 向后移动,以便下次循环使用更新的丑数;如果是乘以 3 或 5 得到的,也分别移动指针 i3 和 i5。复杂度分析时间复杂度:O(N),因为我们只需要生成 N 个丑数,每次生成一个丑数的操作时间是常数。空间复杂度:O(N),因为我们使用了一个长度为 N 的数组来存储丑数。😄总结丑数问题通过动态规划的方式,巧妙地利用三个指针生成新的丑数,并且保证了每个丑数都是按顺序生成的。通过这种方式,我们可以在 O(N) 的时间内得到第 N 个丑数,是一种高效的解决方案。
  • StoryDiffusion漫画创作节活动分享-VOD/创意
    进入活动链接:https://pangu.huaweicloud.com/gallery/asset-detail.html?id=c1cf0774-59ce-44fc-a4a8-8fcf026d2fec1、切换规格为64GB的限时免费规格2、点击执行3、然后执行:4、继续执行5、切换python版本,这个很重要!!!!,6、安装和启动运行7、最后生成了一个链接:Running on public URL: https://0dfb450b322dd89a40.gradio.live8、点击该URL,就可以开始使用了角色:man  活动: play basketball,选择风格类型使用效果1,这个是“线条艺术”这个是“油画”效果这个是“日本动画”风格该模型部署起来很方便,模型很强大,伙伴们可以多多探索,多少挖掘
  • [互动交流] 提取CMU- Mosei数据集的特征
    再使用CMU-Multimodal SDK Version 1.2.0提取CMU- Mosei数据集的特征时,程序运行到一半叫我“Please input dimension namescomputational sequence version for computational sequence: ” 该输入什么?