pytorch rpc如何实现分物理机器的mode pipeline

多主机Pytorch RPC连接拒绝问题 一个官方未提及的TP_SOCKET_IFNAME决定了能否成功运行,就挺无语的。以为官方教程就足够了,结果还是需要这样的填坑手册,希望能帮助到其他人。 阅读详情

因为业务需要,最近接到一项任务,是如何利用pytorch实现model parallel以及distributed training。搜罗了网上很多资料,以及阅读了pytorch官方的教程,都没有可参考的案例。讲的比较多的是data parallel,关于model parallel以及model pipeline的研究发现不多。
通过阅读pytorch官方主页,发现这个example是进行分布式的model pipeline的,
官方博客地址:DISTRIBUTED PIPELINE PARALLELISM USING RPC
官方的example地址:Distributed Pipeline Parallel Example
通过阅读代码发现,这个代码以Resnet 50 model为例,将model直接拆分成两部分,并指定两部分在不同的worker运行,代码实现了在同一台机器上,创建多进程来拆分模型运行。关于这个代码的详细介绍可搜索关键词:pytorch RPC 的分布式管道并行,这里不多介绍。
通过在本地运行代码发现,不满足多机器运行的需求。接下来是思考的心路里程。

  1. 首先通过代码发现,python main.py程序运行时,无法指定rank,那么在跨机器运行时如何知道哪台机器是worker1,worker2?这个地方,我们首先怀疑需要去修改worker,人为在代码中指定worker的IP地址,如修改main.py 代码中191行
    修改前:
    model = DistResNet50(split_size, ["worker1", "worker2"])
    修改后:
    model = DistResNet50(split_size, ["worker1@xxx.xxx.xxx.xxx", "worker2@xxx.xxx.xxx.xxx"])
    然后,很自然的就报错了,这里无法识别这样的worker名,不支持直接指定,这条路也就走不通了。
  2. 接着只能重新阅读代码,到最后251行,我们发现
    mp.spawn(run_worker, args=(world_size, num_split), nprocs=world_size, join=True)
    尤其是这行代码中mp.spawn引起了我们的怀疑,这不是多进程么,这本质还是在多进程情况下来执行程序,无法跨机器啊,不符合我们的需求。
  3. 最后的最后,我们重新阅读pytorch rpc机制,并通过简单测试程序,让两台机器互相通信,其中一台机器发起运算请求并传输原始数据,另外一台机器负责接收数据并进行相关运算,这个程序当时在两台物理机器上测试成功了,那说明rpc实现通信这件事并不复杂。结合前面给的代码,我们决定将worke1和worker2分开写代码,分开执行,并且在代码中需要指定这些worker所属的rank,这样理论上就能够将原始代码修改成分机器的rpc通信运行了。

上面主要是我们的心理历程,话不多说,接下来show the code。
实验环境,两台机器,均是cpu环境,conda安装的环境也保证了一致。
master机器代码:


# https://github.com/pytorch/examples/blob/main/distributed/rpc/pipeline/main.py

import os
import threading
import time
import torch
import torch.nn as nn
import torch.distributed.autograd as dist_autograd
import torch.distributed.rpc as rpc
import torch.optim as optim
from torch.distributed.optim import DistributedOptimizer
from torch.distributed.rpc import RRef

from torchvision.models.resnet import Bottleneck
os.environ['MASTER_ADDR'] = 'XXX.XXX.XXX.XXX' # 指定master ip地址
os.environ['MASTER_PORT'] = '7856' # 指定master 端口号

#########################################################
#           Define Model Parallel ResNet50              #
#########################################################

# In order to split the ResNet50 and place it on two different workers, we
# implement it in two model shards. The ResNetBase class defines common
# attributes and methods shared by two shards. ResNetShard1 and ResNetShard2
# contain two partitions of the model layers respectively.


num_classes = 1000


def conv1x1(in_planes, out_planes, stride=1):
    """1x1 convolution"""
    return nn.Conv2d(in_planes, out_planes, kernel_size=1, stride=stride, bias=False)

class ResNetBase(nn.Module):
    def __init__(self, block, inplanes, num_classes=1000,
                 groups=1, width_per_group=64, norm_layer=None):
        super(ResNetBase, self).__init__()

        self._lock = threading.Lock()
        self._block = block
        self._norm_layer = nn.BatchNorm2d
        self.inplanes = inplanes
        self.dilation = 1
        self.groups = groups
        self.base_width = width_per_group

    def _make_layer(self, planes, blocks, stride=1):
        norm_layer = self._norm_layer
        downsample = None
        previous_dilation = self.dilation
        if stride != 1 or self.inplanes != planes * self._block.expansion:
            downsample = nn.Sequential(
                conv1x1(self.inplanes, planes * self._block.expansion, stride),
                norm_layer(planes * self._block.expansion),
            )

        layers = []
        layers.append(self._block(self.inplanes, planes, stride, downsample, self.groups,
                                  self.base_width, previous_dilation, norm_layer))
        self.inplanes = planes * self._block.expansion
        for _ in range(1, blocks):
            layers.append(self._block(self.inplanes, planes, groups=self.groups,
                                      base_width=self.base_width, dilation=self.dilation,
                                      norm_layer=norm_layer))

        return nn.Sequential(*layers)

    def parameter_rrefs(self):
        r"""
        Create one RRef for each parameter in the given local module, and return a
        list of RRefs.
        """
        return [RRef(p) for p in self.parameters()]


class ResNetShard1(ResNetBase):
    """
    The first part of ResNet.
    """
    def __init__(self, device, *args, **kwargs):
        super(ResNetShard1, self).__init__(
            Bottleneck, 64, num_classes=num_classes, *args, **kwargs)

        self.device = device
        self.seq = nn.Sequential(
            nn.Conv2d(3, self.inplanes, kernel_size=7, stride=2, padding=3, bias=False),
            self._norm_layer(self.inplanes),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2, padding=1),
            self._make_layer(64, 3),
            self._make_layer(128, 4, stride=2)
        ).to(self.device)

        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
            elif isinstance(m, nn.BatchNorm2d):
                nn.init.ones_(m.weight)
                nn.init.zeros_(m.bias)

    def forward(self, x_rref):
        x = x_rref.to_here().to(self.device)
        with self._lock:
            out =  self.seq(x)
        return out.cpu()


class ResNetShard2(ResNetBase):
    """
    The second part of ResNet.
    """
    def __init__(self, device, *args, **kwargs):
        super(ResNetShard2, self).__init__(
            Bottleneck, 512, num_classes=num_classes, *args, **kwargs)

        self.device = device
        self.seq = nn.Sequential(
            self._make_layer(256, 6, stride=2),
            self._make_layer(512, 3, stride=2),
            nn.AdaptiveAvgPool2d((1, 1)),
        ).to(self.device)

        self.fc =  nn.Linear(512 * self._block.expansion, num_classes).to(self.device)

    def forward(self, x_rref):
        x = x_rref.to_here().to(self.device)
        with self._lock:
            out = self.fc(torch.flatten(self.seq(x), 1))
        return out.cpu()


class DistResNet50(nn.Module):
    """
    Assemble two parts as an nn.Module and define pipelining logic
    """
    def __init__(self, split_size, workers, *args, **kwargs):
        super(DistResNet50, self).__init__()

        self.split_size = split_size

        # Put the first part of the ResNet50 on workers[0]
        self.p1_rref = rpc.remote(
            workers[0],
            ResNetShard1,
            args = ("cuda:0",) + args,
            kwargs = kwargs
        )

        # Put the second part of the ResNet50 on workers[1]
        self.p2_rref = rpc.remote(
            workers[1],
            ResNetShard2,
            args = ("cpu",) + args,
            kwargs = kwargs
        )

    def forward(self, xs):
        # Split the input batch xs into micro-batches, and collect async RPC
        # futures into a list
        out_futures = []
        for x in iter(xs.split(self.split_size, dim=0)):
            x_rref = RRef(x)
            y_rref = self.p1_rref.remote().forward(x_rref)
            print(y_rref)
            z_fut = self.p2_rref.rpc_async().forward(y_rref)
            print(z_fut)
            out_futures.append(z_fut)

        # collect and cat all output tensors into one tensor.
        return torch.cat(torch.futures.wait_all(out_futures))

    def parameter_rrefs(self):
        remote_params = []
        remote_params.extend(self.p1_rref.remote().parameter_rrefs().to_here())
        remote_params.extend(self.p2_rref.remote().parameter_rrefs().to_here())
        return remote_params


#########################################################
#                   Run RPC Processes                   #
#########################################################

num_batches = 3
batch_size = 8
image_w = 128
image_h = 128

if __name__=="__main__":
    options = rpc.TensorPipeRpcBackendOptions(num_worker_threads=256, rpc_timeout=300)
    # 初始化主节点的RPC连接
    rpc.init_rpc("master", rank=0, world_size=2, rpc_backend_options=options)

    for num_split in [1,2]:
        tik = time.time()

        model = DistResNet50(num_split, ["master", "worker"])
        loss_fn = nn.MSELoss()
        opt = DistributedOptimizer(
            optim.SGD,
            model.parameter_rrefs(),
            lr=0.05,
        )
        one_hot_indices = torch.LongTensor(batch_size) \
            .random_(0, num_classes) \
            .view(batch_size, 1)

        for i in range(num_batches):
            print(f"Processing batch {i}")
            # generate random inputs and labels
            inputs = torch.randn(batch_size, 3, image_w, image_h)
            labels = torch.zeros(batch_size, num_classes) \
                .scatter_(1, one_hot_indices, 1)

            with dist_autograd.context() as context_id:
                outputs = model(inputs)
                dist_autograd.backward(context_id, [loss_fn(outputs, labels)])
                opt.step(context_id)

        tok = time.time()
        print(f"number of splits = {num_split}, execution time = {tok - tik}")

    # 关闭RPC连接
    rpc.shutdown()

worker端的代码


# https://github.com/pytorch/examples/blob/main/distributed/rpc/pipeline/main.py

import os
import threading
import time
from functools import wraps

import torch
import torch.nn as nn
import torch.distributed.rpc as rpc
from torch.distributed.rpc import RRef

from torchvision.models.resnet import Bottleneck
os.environ['MASTER_ADDR'] = 'XXX.XXX.XXX.XXX' # 指定master 端口号
os.environ['MASTER_PORT'] = '7856' # 指定master 端口号

#########################################################
#           Define Model Parallel ResNet50              #
#########################################################

# In order to split the ResNet50 and place it on two different workers, we
# implement it in two model shards. The ResNetBase class defines common
# attributes and methods shared by two shards. ResNetShard1 and ResNetShard2
# contain two partitions of the model layers respectively.


num_classes = 1000


def conv1x1(in_planes, out_planes, stride=1):
    """1x1 convolution"""
    return nn.Conv2d(in_planes, out_planes, kernel_size=1, stride=stride, bias=False)

class ResNetBase(nn.Module):
    def __init__(self, block, inplanes, num_classes=1000,
                 groups=1, width_per_group=64, norm_layer=None):
        super(ResNetBase, self).__init__()

        self._lock = threading.Lock()
        self._block = block
        self._norm_layer = nn.BatchNorm2d
        self.inplanes = inplanes
        self.dilation = 1
        self.groups = groups
        self.base_width = width_per_group

    def _make_layer(self, planes, blocks, stride=1):
        norm_layer = self._norm_layer
        downsample = None
        previous_dilation = self.dilation
        if stride != 1 or self.inplanes != planes * self._block.expansion:
            downsample = nn.Sequential(
                conv1x1(self.inplanes, planes * self._block.expansion, stride),
                norm_layer(planes * self._block.expansion),
            )

        layers = []
        layers.append(self._block(self.inplanes, planes, stride, downsample, self.groups,
                                  self.base_width, previous_dilation, norm_layer))
        self.inplanes = planes * self._block.expansion
        for _ in range(1, blocks):
            layers.append(self._block(self.inplanes, planes, groups=self.groups,
                                      base_width=self.base_width, dilation=self.dilation,
                                      norm_layer=norm_layer))

        return nn.Sequential(*layers)

    def parameter_rrefs(self):
        r"""
        Create one RRef for each parameter in the given local module, and return a
        list of RRefs.
        """
        return [RRef(p) for p in self.parameters()]

class ResNetShard2(ResNetBase):
    """
    The second part of ResNet.
    """
    def __init__(self, device, *args, **kwargs):
        super(ResNetShard2, self).__init__(
            Bottleneck, 512, num_classes=num_classes, *args, **kwargs)

        self.device = device
        self.seq = nn.Sequential(
            self._make_layer(256, 6, stride=2),
            self._make_layer(512, 3, stride=2),
            nn.AdaptiveAvgPool2d((1, 1)),
        ).to(self.device)

        self.fc =  nn.Linear(512 * self._block.expansion, num_classes).to(self.device)

    def forward(self, x_rref):
        x = x_rref.to_here().to(self.device)
        print(x)
        with self._lock:
            out = self.fc(torch.flatten(self.seq(x), 1))
        return out.cpu()


#########################################################
#                   Run RPC Processes                   #
#########################################################



if __name__=="__main__":
    options = rpc.TensorPipeRpcBackendOptions(num_worker_threads=256, rpc_timeout=300)
    # 初始化工作节点的RPC连接
    rpc.init_rpc("worker", rank=1, world_size=2, rpc_backend_options=options)

    # 等待主节点的调用
    rpc.shutdown()

代码中的MASTER_ADDR和port需要指定为一致,分别在master机器上运行master.py,worker机器上运行worker.py,这样就可以实现Resnet 50 model在两台物理机器上分布式model pipeline。
注意事项

  • 确保物理机器能够互相ping通,同时关闭防火墙
  • 两个物理机器最好都是linux环境,我们的实验发现pytorch的分布式不支持在Windows环境运行
  • 两个物理机器的python运行环境要求保持一致
PyTorch与TensorFlow深度对比:从科研训练到工业部署的选型决策指南 深度学习框架是连接算法创新与工程落地的核心枢纽,其本质是自动微分、内存管理与硬件加速三位一体的计算图引擎。PyTorch以命令式执行提供极致调试自由与动态建模能力,适合快速原型、算法探索和复杂结构定制;TensorFlow则依托声明式契约与tf.function编译,在大规模分布式训练、TFX生产流水线及TensorFlow Lite边缘量化部署中展现确定性优势。二者在模型定义灵活性、数据加载优化策略(DataLoader vs tf.data)、分布式训练抽象层级(DDP显式控制 vs MirroredS 阅读详情

相关推荐

机器学习模型上线后的生存指南:从部署陷阱到监控闭环

机器学习模型部署不是开发终点,而是系统性挑战的起点。当模型脱离离线环境进入真实业务流,其稳定性高度依赖数据时效性、接口契约一致性、特征管道可靠性等隐性工程能力。本文围绕模型服务化过程中的核心痛点——如特征延迟、上游接口静默变更、重试雪崩、环境差异、可观测性缺失等,结合金融级风控等高要求场景,系统阐述如何构建具备反脆弱性的ML生产系统。内容涵盖部署集成规范、性能压测方法论、数据与特征漂移检测机制,以及面向合规与运维的全链路监控体系,助力团队跨越‘模型上线即崩溃’的死亡之谷。

weixin_34377919的博客 394

[源码解析] PyTorch 分布式(17) --- 结合 DDP 和分布式 RPC 框架

在前面的文章之中,我们已经学习了PyTorch 分布式的基本模块,接下来我们通过几篇文章来看看如何把这些模块应用到实践之中,顺便把PyTorch分布式逻辑整体梳理一下。本文介绍如何把DDP和RPC framework结合起来。

罗西的思考 897

Agentic RL训练独立部署:进程/网络/数据三重隔离实践

Agentic RL(基于智能体的强化学习)作为一种融合决策、工具调用与环境交互的新型AI范式,其训练过程天然具备高并发、强状态依赖和多系统耦合等特征。若与业务系统共享进程、网络或数据库资源,极易引发延迟飙升、数据污染与服务雪崩。因此,实现训练与业务的物理级隔离——包括进程运行时硬隔离(如cgroup/K8s Job资源锁死)、训练流量绕过API网关构建专用服务网格、轨迹数据写入独立时序数据库(如TimescaleDB)并禁止反向读取——已成为保障系统稳定性与模型可演进性的工程底线。该架构不仅支撑仿真环境沙

优快云头条 483

[源码解析] PyTorch 分布式(18) --- 使用 RPC 的分布式管道并行

在前面的文章之中,我们已经学习了PyTorch 分布式的基本模块,接下来我们通过几篇文章来看看如何把这些模块应用到实践之中,顺便把PyTorch分布式逻辑整体梳理一下。本文介绍如何使用 RPC 来完成分布式管道并行。

罗西的思考 1044

MLOps实战:解决模型退化、数据漂移与生产监控四大难题

MLOps 是面向机器学习系统在生产环境中持续交付与可靠运行的工程范式,其核心在于应对数据腐烂、特征漂移、模型退化等概率性系统固有挑战。不同于传统DevOps的确定性逻辑,MLOps需构建覆盖数据层、模型层、业务层的多维监控体系,并通过原子快照版本控制、特征服务化、动态基线告警等关键技术保障可重复性与可审计性。它支撑从电商推荐、金融风控到医疗影像等真实场景的稳定迭代,本质是将‘能跑通’升级为‘能扛住、可归因、易治理’的工业级AI能力。本文聚焦落地中高频出现的模型性能骤降、特征不一致、监控误报等典型问题,提供

chenshixi3325的博客 455

LLM作为新操作系统内核:开源模型工程落地全链路指南

大语言模型(LLM)正从对话接口演进为可编程的语义处理器,其核心能力——意图理解、工具调用、多模态感知与代码执行——已具备类操作系统内核的关键特征,如进程调度、内存管理与系统调用。这一范式迁移带来显著技术价值:降低AI系统复杂度、提升部署灵活性、增强业务嵌入深度。在实际工程中,Mistral-7B、Qwen-7B等开源模型凭借GQA优化、RoPE长上下文支持及Apache 2.0许可,正快速替代闭源方案,成为推理服务、RAG系统与边缘部署的首选。本文聚焦LLM作为系统内核的工程实现路径,覆盖模型选型决策树、

bangtuo9862的博客 371

PyTorch 2.2 中文官方教程(十九)

使用 RPC 进行分布式管道并行 原文:pytorch.org/tutorials/intermediate/dist_pipeline_parallel_tutorial.html 译者:飞龙 协议:CC BY-NC-SA 4.0 作者:Shen Li 注意 在github中查看并编辑本教程。 先决条件: PyTorch 分布式概述 单机模型并行最佳实践 开始使用分布式 RPC 框架 RRef 辅助函数:RRef.rpc_sync()、RRef.rpc_async()和RRef.re

龙哥盟 2186

Stargate:用Protocol Buffers重构数据科学家的模型交付契约

在MLOps实践中,'模型即代码'范式常导致离线与线上结果不一致、跨团队协作低效等核心问题。其本质是缺乏可验证、可追溯、可执行的服务契约。Protocol Buffers凭借强类型定义、向后兼容性保障和高效二进制序列化,成为构建模型输入/输出契约的理想载体——它不仅支撑gRPC高性能通信,更驱动特征一致性校验、灰度发布路由与自动化契约测试。本文聚焦Stargate框架如何以.proto文件为中枢,将数据科学家角色从代码编写者升级为契约设计师,并在金融风控与电商推荐等高敏场景中实现日均37次原子化模型交付。

dbp5156的博客 793

PyTorch 分布式概述

从 PyTorch v1.6.0 开始,分布式数据并行训练(DDP)是一种广泛采用的单程序多数据训练范例。使用 DDP,可以在每个流程上复制模型,并且每个模型副本都将获得一组不同的输入数据样本。DDP 负责梯度通信,以保持模型副本同步,并使其与梯度计算重叠,以加快训练速度。基于 RPC 的分布式训练(RPC)开发来支持无法适应数据并行训练的常规训练结构,例如分布式管道并行性,参数服务器范式以及 DDP 与其他训练范式的组合。它有助于管理远程对象的生命周期,并将自动微分引擎扩展到机器范围之外。集体通信。

yanglamei1962的博客 820

【信息科学与工程学】【数据中心】 第三篇 智算中心全业务场景矩阵

技术:MPI/OpenMP优化、InfiniBand/RoCE网络、Lustre/GPFS并行文件系统。技术:NVLink/NVSwitch高速互联、RDMA网络、检查点存储、混合精度训练。技术:Kubernetes运营商、服务网格、Serverless框架。技术:VXLAN/EVPN、SRv6、智能网卡、DPDK/智能网卡。运营:AI框架优化、显存优化、容错训练、多租户GPU隔离。技术:KVM/ESXi虚拟化、SR-IOV、智能网卡、快速发放。

weixin_49199313的博客 1073

【信息科学与工程学】【数据中心】 第七篇 智算中心CLOS组网整体设计

区域主要功能网络要求技术选型安全等级可用性要求训练区​大规模AI模型训练,分布式计算超高带宽(100G+),超低延迟(<1ms),无损网络RoCEv2,PFC,DCQCN,多路径P4(最高)99.99%推理区​实时AI推理,模型服务低延迟(<10ms),高可用,弹性扩展智能负载均衡,服务网格,容器网络P3(高)99.999%公共服务区​统一认证,API网关,数据服务多租户隔离,安全防护,弹性带宽VXLAN,EVPN,微隔离P3(高)99.99%存储区​高性能存储,数据湖超高带宽,低延迟,高IOPSNVMe-

weixin_49199313的博客 1371

Uber机器学习工程化实践:可复现性与在线/离线一致性落地指南

机器学习模型从实验室走向生产环境,核心挑战并非算法精度,而是系统级的稳定性与可信度。可复现性确保模型在任意环境、任意时间都能产出一致结果;在线/离线一致性则保障训练与服务阶段的数据、特征、逻辑严格对齐——二者共同构成ML工程化的基石。这背后涉及数据快照、环境锁定、特征DSL、GitOps流水线等关键技术手段,直接决定模型能否在高并发、低延迟、强监管的真实业务场景中长期可靠运行。本文基于Uber大规模落地经验,解析如何将抽象原则转化为可审计、可验证、可回滚的工程实践。

A458545418的博客 481

【信息科学与工程学】【数据科学】第一百二十二篇 大数据产品中的函数与算法01

它通常指。下面按照你给出的表格列💡 说明:下表中的"产品"以开源/主流商业组件为具象载体(Hadoop、Spark、Flink、Kafka、Hive、HBase、Iceberg、Atlas、Ranger、TensorFlow 等),它们共同构成一个完整的大数据产品家族;代码为实现示例,用于说明算法在工程系统中的落地方式。

weixin_49199313的博客 198

强化学习策略服务(Policy Serving)工程实践:从模型部署到实时控制

强化学习(Reinforcement Learning)是机器学习的重要分支,通过智能体与环境的交互学习最优决策策略。其核心原理在于基于奖励信号的试错学习,最终目标是获得一个能够在新环境中做出有效决策的策略模型(Policy Model)。这一技术的价值在于能够解决序列决策问题,广泛应用于机器人控制、游戏AI、自动驾驶等领域。在实际应用中,训练好的策略模型需要被部署到生产环境,这就涉及到策略服务(Policy Serving)这一关键技术环节。策略服务负责将训练好的模型转化为稳定、低延迟的在线推理服务,确保

cnracht8153的博客 352

Python-PyText是一个采用PyTorch构建基于深度学习的NLP建模框架

PyText 是一个工业级的开源 NLP 工具包,可用于在 PyTorch 中开发 NLP 模型,并通过 ONNX 部署。其预训练模型包括文本分类、序列标注等。」

Label Studio保姆级教程:从零搭建医疗影像标注平台(DICOM格式支持)

本文提供基于Label Studio从零搭建医疗影像标注平台的保姆级教程。针对DICOM格式支持,详细阐述了环境部署、DICOM深度集成与预处理、团队协作权限管理以及质量审核闭环等核心环节,旨在构建一个高效、可落地的医疗AI数据标注解决方案,助力模型落地。

nft7creator的博客 304

从Notebook到生产环境的ML交付:四层架构与可信契约

机器学习模型部署不是简单的代码打包与容器化,而是跨越数据一致性、环境可重现性、服务可观测性与业务可治理性的系统工程。其核心在于解决模型在真实场景中面临的特征漂移、依赖冲突、API稳定性及成本不可控等关键问题。本文基于27个工业级落地项目经验,提出分层解耦的四层生产就绪架构——Notebook沙箱层保障训练环境冻结、模型注册层强制schema与业务规则验证、特征服务层通过gRPC实现强契约与零信任调用、模型服务层聚焦纯推理与熔断降级。技术价值体现在可审计的日志链路、可复现的conda环境快照、可熔断的API网

weixin_30352191的博客 342

云桌面如何部署?云桌面系统方案部署详细教程

云桌面作为一种比较新的技术工具,核心解决的场景是方便设计师的灵活办公,本身技术就是非常的灵活性,所以在安装部署方面青椒云也做到了十足的灵活。

2301_79113726的博客 1633

数据科学家的Docker实战:构建可复现的数据科学容器环境

Docker 是一种容器化技术,通过镜像分层、内容哈希和联合文件系统,实现运行时环境的可描述、可固化与可验证。其核心原理在于将操作系统、语言运行时、依赖库及应用代码封装为不可变镜像,从而解决 Python 版本漂移、包版本冲突、C 扩展编译失败等数据科学高频环境故障。该技术显著提升协作效率与交付可靠性,广泛应用于本地开发(如 VS Code Remote-Containers)、模型训练(Docker Compose 编排)、服务化部署(FastAPI 封装)等场景。对数据科学家而言,掌握 Dockerfi

weixin_30247307的博客 397

AUTOSAR进阶图解==>AUTOSAR_SWS_COM

AUTOSAR COM模块是AUTOSAR通信堆栈的核心组件,提供信号导向的通信服务。该模块位于通信服务层,连接RTE与PDU Router,主要功能包括信号封装/提取、传输模式管理、信号路由、超时监控和字节序转换等。COM模块架构分为应用层、通信服务层和通信抽象层,包含信号管理、I-PDU处理、传输模式管理等组件。其配置结构包括顶层容器、I-PDU组、I-PDU和信号等多层次配置对象,支持丰富的参数设置。模块采用严格的状态管理机制,包括模块状态和I-PDU组状态转换,确保通信可靠性。

一名留德华的,康德的信徒的,专注于汽车电子领域的博客 1243

基于STM32单片机智能循迹小车毕业设计

本文介绍了一种利用STM32F103C8T6单片机为控制核心,结合多种传感器以及PID算法实现循迹避障功能的智能小车。随着我国高科技水平的不断提高和工业自动化进程的不断推进,智能小车被广泛应用于各种玩具和其他产品的设计中,极大地丰富了人们的生活。本次设计利用反射式红外光电传感器探测路面黑线实现小车循迹,利用超声波测距传感器探测路径上的障碍,控制小车自动避障,整个系统具有自动循迹、自动避障、速度检测和无线遥控功能。其中,控制部分采用STM32F103C8T6单片机,STM32F103C8T6单片机是一

qq_48771816的博客 3974

Ray分布式实战:Python原生分布式编程的轻量级落地指南

分布式计算本质上是将任务调度、状态管理与资源隔离抽象为可复用的编程模型。其核心原理在于通过任务(Task)、有状态服务(Actor)和共享对象(Object)三类原语,解耦计算逻辑与基础设施。技术价值体现在显著降低Python生态的分布式心智负担——无需重写算法、不强制数据格式转换、支持PyTorch/TensorFlow等主流框架原生运行。典型应用场景包括批量特征工程加速、超参搜索并行化、实时推理服务扩缩容及遗留脚本快速多机扩展。本文聚焦Ray Core底层行为边界与生产级部署实践,深入解析@ray.re

weixin_30755393的博客 406

Level 4自动驾驶系统设计49——L4 架构设计 2

在 9.3.2 节所述的 SerDes 晶圆级原生“双出(Splitter Mode)”物理架构中,若解串芯片内部的其中一路 MIPI 供电轨因大算力 SoC 1 的高热漏电流污染突发二阶瞬态电磁耦合,导致双出通道产生 $\mathbf{\Delta} \text{Skew} \ge 15\text{ps}$ 的时序偏置。其中,$\mathbf{H}(t)$ 为最低限度生存网雷达几何测量的观测矩阵,$\mathbf{R}_{\text{fallback}}$ 为清洗后的雷达测量不确定度协方差。

Godspeed_zwh的博客 309
上一篇: Ubuntu利用anaconda安装TensorFlow-gpu版本以及安装paddle-gpu版本
下一篇: Knowledge Distillation: A Survey
UnknownBody
博客等级 码龄16年 5600粉丝 4725原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UnknownBody

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值