顶部
首页

三个月、零基础手搓一块TPU, 能推理能训练, 还是开源的

三个月、零基础手搓一块TPU, 能推理能训练, 还是开源的

更新时间: 浏览次数: 258

最近,大模型技术的发展,让人们再次重视起 AI 专用芯片。

对于计算任务负载来说,越是专用,效率就越高,谷歌的 TPU 就是其中的一个典型例子。它自 2015 年开始在谷歌数据中心部署后,已经发展到了第 7 代。目前的最新产品不仅使用了最先进的制程工艺打造,也在架构上充分考虑了对于机器学习推理任务的优化。TPU 的出现,促进了 Gemini 等大模型技术的进展。

这种芯片为何性能如此强大?或许最直接的了解方法就是尝试复刻它。近日,来自加拿大西安大略大学的工程师 Surya Sure 等人宣布已经利用暑假时间构建出了 TinyTPU:一种开源的 ML 推理、训练芯片。

项目 GitHub 地址:https://github.com/tiny-tpu-v2/tiny-tpu

有趣的是,他们并非芯片设计专业的学生,打造 TPU 是从理解多层感知机(MLP)这样的神经网络基本概念开始的。为此,他们还手工计算了网络推理和训练所需的数学运算。

让我们看看他是如何做到的。

手搓 TPU 的原因

选择造一块 TPU 的原因很简单:

构建一个用于机器学习工作负载的芯片看起来很酷;

之前还没有一个同时进行推理和训练的机器学习加速器的完整开源代码库。

我们都没有真正的硬件设计专业经验,这在某种程度上使得 TPU 更具吸引力,因为我们无法准确估计它的难度。在项目初期,我们确立了严格的设计理念:始终尝试「Hacky Way」(不靠谱的方法)。这意味着在咨询外部资源之前,先尝试那些我们首先想到的「愚蠢」想法。这种理念确保了我们没对 TPU 进行逆向工程,而是对其进行重新发明,因此我们自己推导出了 TPU 中使用的许多关键机制。

我们也想把这个项目当作一次不依赖人工智能代写代码的练习,因为我们感觉最近每当遇到小问题时,我们的第一反应就是求助于这些 AI 工具。我们希望培养一种特定的思维方式,以便我们能够将其付诸实践,并在未来的任何努力中运用它来解决难题。

在整个项目过程中,我们尽可能多地学习深度学习、硬件设计和算法创建方面的基础知识。我们发现,学习这些知识的最佳方式是将所有知识都画出来,并将其作为我们的第一反应。阅读这篇文章时,你会发现我们的解释是如何受到这种理念的启发的。

在继续之前,我们想先明确一下这篇文章涵盖的内容和不涵盖的内容。请注意,本文并非 TPU 的 1:1 复制品 —— 而是我们自己重新发明 TPU 的尝试。

什么是 TPU?

TPU 是谷歌设计的一款专用芯片 (ASIC),旨在专门提高机器学习模型的推理和训练速度。GPU 既可以渲染图像,又可以运行机器学习工作负载,而 TPU 专用于执行数学运算,这使得它能够更高效率地完成其设计初衷。在芯片领域,尝试掌握单个任务比尝试掌握多个任务更容易,而且效果也更好,而 TPU 正是秉承了这一理念。

硬件设计快速入门:

在硬件中,我们处理的时间单位称为时钟周期。作为开发者,我们可以根据需要设置任意的时间段。通常,单个时钟周期的范围从 1 皮秒 (ps) 到 1 纳秒 (ns),我们运行的任何操作都将在时钟周期之间执行。

时钟周期时序图展示了硬件中操作的同步方式。

我们用来描述硬件的语言叫做 Verilog。它是一种硬件描述语言,允许我们描述给定硬件模块的行为(类似于软件中的函数),但它不是以程序的形式执行,而是合成布尔逻辑门(AND 与、OR 或、NOT 非等),这些逻辑门可以组合起来,构建我们想要的任何芯片的数字逻辑。以下是 Verilog 中加法运算的一个简单示例:

在上面的例子中,信号 b 在下一个时钟周期的值被设置为信号 a 的当前值。你会发现,在大多数情况下,信号(变量)是按顺序的时钟周期更新的,而不是像软件设计中那样立即更新。

具体来说,TPU 在执行矩阵乘法方面非常高效,它占 Transformer 计算操作的 80-90%(在超大型模型中高达 95%),以及 CNN 计算操作的 70-80%。每个矩阵乘法都代表 MLP(多层感知器)中单个层的计算,而在深度学习中,我们拥有多层级的 MLP,这使得 TPU 在处理大型模型时更加高效。

那么如何构建一块 TPU 呢?

当我们开始这个项目时,我们只知道方程 y = mx + b 是神经网络的基础构建块。然而,我们需要完全理解神经网络背后的数学原理,才能在 TPU 中构建其他模块。因此在开始编写任何代码之前,我们每个人都计算出了一个简单的 2 → 2 → 1 多层感知器 (MLP) 的数学原理。

用于解决 XOR 问题的 2→2→1 多层感知器的架构。

我们选择这个特定网络的原因是,我们的目标是针对 XOR 问题(神经网络的「Hello World」)进行推理和训练。XOR 问题是神经网络可以解决的最简单的问题之一。所有其他门(AND、OR 等)都可以仅使用一条线性线(一个神经元)来区分哪些输入对应于 0,哪些输入对应于 1,从而根据输入预测输出。但是,要对所有 XOR 进行分类,需要一个 MLP,因为它需要弯曲的决策边界,而这仅靠线性方程无法实现。

对于几何和第一性原理的论述,免费书籍《理解深度学习》(Understanding Deep Learning)非常值得一读:https://udlbook.github.io/udlbook/

现在,假设我们要进行连续推理(例如,自动驾驶汽车每秒进行多个预测)。这意味着我们需要同时发送多条数据。由于数据本质上是多维的,并且具有许多特征,因此我们需要非常大的矩阵维度。然而,XOR 问题简化了维度,因为只有两个特征(0 或 1)和 4 种可能的输入数据(0 和 1 的四种二进制组合)。这为我们提供了一个 4x2 矩阵,其中 4 是行数(批处理大小 batch size),2 是列数(特征大小)。

XOR 输入矩阵和目标输出:

每一行代表四个可能的异或输入之一,输出向量显示预期的异或结果。

我们对脉动阵列示例进行的另一项简化是,我们将使用 2x2 阵列,而不是 TPUv1 中使用的 256x256 阵列。然而,数学运算仍然忠实于原有的格式,因此实际上并没有简化,而是进行了规模缩小。

等式的第一步是将 m 与 x 相乘,以矩阵形式表示为 XW^T:

其中 X 是我们的输入矩阵,W 是我们的权重矩阵,b 是我们的偏差向量。

我们如何在硬件中执行矩阵乘法?嗯,我们可以使用一个叫做脉动阵列的单元!

TPU 的核心是一个叫做脉动阵列(systolic array)的单元。它由称为处理单元 (PE) 的独立构建块组成,这些构建块以网格状结构连接在一起。每个 PE 执行乘法 - 累加运算,这意味着它将传入的输入 X 与固定权重 W 相乘,并将其与传入的累加和相加,所有这些都在同一个时钟周期内完成。

处理元件(PE)架构显示乘法累加运算(无负载权重和启动标志)。

当这些 PE 连接在一起时,它们可以以脉动方式执行矩阵乘法,这意味着每个时钟周期都可以计算输出矩阵的多个元素。输入从左侧进入脉动阵列,然后每个时钟周期移动到右侧相邻的 PE。累加和从第一行 PE 的乘法输出开始,向下移动,并与每个连续 PE 的乘积相加,直到到达最后一行 PE,成为输出矩阵的一个元素。

脉动阵列架构展示了 PE 如何连接以执行矩阵乘法。

由于 TPU 只有一个单元(并且矩阵乘法在模型中占据了主要计算量),因此它可以非常轻松地推理和训练任何模型。

示例

现在,让我们来看看异或问题的示例。

我们的脉动阵列接受两个输入:输入矩阵和权重矩阵。对于我们的异或网络,使用以下权重和偏差进行初始化:

输入和权重调度

为了将输入批次输入到脉动阵列中,我们需要:

将 X 矩阵旋转 90 度

矩阵旋转 90 度,为脉动阵列输入做准备。

错开输入(将每行延迟 1 个时钟周期)

用于脉动阵列处理的输入矩阵交错模式。

要输入我们的权重矩阵,我们需要:

交错排列权重矩阵(与输入类似)

用于脉动阵列处理的权重矩阵交错模式

转置它!

权重矩阵转置以实现正确的数学对齐。

请注意,旋转和交错没有任何数学意义 —— 它们只是为了使脉动阵列正常工作。转置也只是为了进行数学记账 —— 它是使矩阵数学运算正常工作所必需的,因为我们在神经网络图中设置权重指针的方式。

交错和先进先出 (FIFO)

为了执行交错,我们为权重和输入设计了几乎相同的累加器,分别位于脉动阵列的上方和左侧。

由于激活是逐个输入到脉动阵列中的,我们认为先进先出队列 (FIFO) 是最佳的数据存储方案。然而,传统的 FIFO 和我们构建的累加器之间略有不同。我们的累加器有两个输入端口 —— 一个用于手动将权重写入 FIFO,另一个用于将激活模块的上一层输出写回到输入 FIFO(上一层的输出是当前层的输入)。

我们还需要以类似的方式为每一层加载权重,因此我们复制了权重 FIFO 的逻辑,但没有第二个端口。

脉动阵列矩阵乘法:

偏差和激活

等式的下一步是添加偏差。为了在硬件中实现这一点,我们需要在脉动阵列的每一列下创建一个偏差模块。我们可以看到,当总和移出脉动阵列的最后一行时,我们可以立即将它们输入到偏差模块中,以计算预激活。我们将用变量 Z 表示这些值。

偏差向量 b 会在矩阵的所有行上转发 —— 这意味着它会被添加到每个 Z 行。

现在,我们的方程看起来很像我们在高中学到的 —— 只不过是多维形式,其中从脉动阵列流出的每一列都代表其自身的特征!

接下来,我们必须应用激活函数,为此我们选择了 Leaky ReLU。[5] 这也是一个逐元素的操作,类似于偏差函数,这意味着我们需要在每个偏差模块下(以及通过代理在脉动阵列的每一列下)都有一个激活模块,并且我们可以将偏差模块的输出立即流式传输到激活模块中。我们将用 H 表示这些激活后的值。

Leaky ReLU 函数逐元素应用:

其中 α=0.5 是我们的泄漏因子。对于矩阵,这适用于每个元素。

以我们的异或运算示例为例,我们来看看第 1 层如何处理数据。首先,脉动阵列计算

然后添加偏差:

最后,LeakyReLU 逐个元素应用:

负值乘以 0.5,正值保持不变。

带偏置和 LeakyReLU 的脉动阵列:

流水线

现在你可能会问 —— 为什么我们不把偏置项和激活项合并在一个时钟周期内?这是因为流水线技术!流水线允许多个操作在 TPU 的不同阶段同时执行 —— 无需等待一个完整的操作完成后再开始下一个操作,而是将工作分解成可以重叠的阶段。

可以把它想象成一条装配线:当一个工作模块(激活模块)处理一个零件时,前一个工作模块(偏置模块)已经在处理下一个零件了。这使得所有模块都保持忙碌状态,而不是让它们闲置等待上一个阶段完成。这也会影响 TPU 的运行速度 —— 如果某个模块试图在一个周期内执行多个操作,那么该模块将成为 TPU 的瓶颈,因为其他模块的运行速度最终只能与该模块相同。因此,尽可能将操作分解成多个时钟周期是高效且最佳实践。

流水线阶段显示操作如何跨时钟周期重叠。

为了尽可能高效地运行芯片,我们采用了另一种机制,即传播「启动」信号,我们称之为「移动芯片使能」(用紫色圆点表示)。由于我们设计中的所有组件都是交错排列的,我们意识到可以非常优雅地在第一个累加器上断言一个时钟周期的启动信号,并在相邻模块需要开启时将其准确传播到它们。

这将延伸到脉动阵列,最终延伸到偏置和激活模块,其中相邻的 PE 和模块(从左上角到右下角)在连续的时钟周期内开启。这确保了每个模块仅在需要时执行计算,并且不会在后台浪费电量。

双倍缓冲

现在,我们知道开始一个新的层意味着我们必须使用新的权重矩阵计算相同的

。如果我们的脉动阵列是权重平稳的,我们该如何做到这一点?我们该如何改变权重?

在思考这个问题时,我们偶然发现了双倍缓冲的概念,它源自电子游戏。双缓冲存在的原因是为了防止显示器上出现所谓「画面撕裂」的情况。归根结底,像素加载需要时间,我们希望以某种方式「隐藏」这段时间。如果你仔细观察,就会发现这与我们目前在脉动阵列中面临的问题完全相同。幸运的是,游戏设计师已经想出了解决这个问题的方案。通过添加第二个「影子」缓冲区(在当前层计算时保存下一层的权重),我们可以在计算过程中加载新的权重,从而将总时钟周期数减少一半。

为了实现这一点,我们还需要添加一些信号来移动数据。首先,我们需要一个信号来指示何时切换影子缓冲区和活动缓冲区中的权重。我们将这个信号称为「切换」信号(用蓝点表示),它将影子缓冲区中的值复制到活动缓冲区。它从脉动阵列的左上角传播到右下角(与移动芯片使能的路径相同,但仅在脉动阵列内传播)。然后,我们需要另一个信号来指示何时需要将权重向下移动一行,我们将其称为「接受」标志(用绿点表示),因为每一行都表示接受一组新的权重。这会将新的权重移动到脉动阵列的顶行,并将每一行权重向下移动到脉动阵列的下一行。这两个控制标志协同工作,使我们的双缓冲机制正常工作。

如果你还没注意到,这让脉动阵列能够执行一项强大的功能…… 持续推理!我们可以持续输入新的权重和输入,并计算任意层级的前向传播。这触及了脉动阵列的核心设计理念:我们希望最大化 PE 的利用率。我们希望始终保持脉动阵列的馈送!

对于第 2 层,第 1 层的输出 (H1)现在成为我们的输入:

添加偏差并应用激活:

所有值均为正数,因此它们会保持不变。这些就是我们对异或问题的最终预测!

正向传递演练(使用双倍缓冲)

控制单元和指令集(ISA)

我们推理的最后一步是创建一个控制单元,使其使用自定义指令集 (ISA) 来断言所有控制标志并通过数据总线加载数据。包括数据总线在内,我们的 ISA 长度为 24 位,这使得我们的测试平台更加优雅,因为我们可以每个时钟周期传递一串位,而无需单独设置多个标志。

然后,我们将所有东西整合在一起,推理功能完全正常运行!这是一个重要的里程碑。

反向传播与训练

好了,我们已经解决了推理问题 —— 那么训练呢?有趣的是,我们可以将用于推理的架构用于训练!为什么?因为训练只是矩阵乘法,只是多了一些步骤。

接下来才是真正令人兴奋的地方。假设我们刚刚对异或问题进行了推理,得到的预测结果类似于 [0.8, 0.3, 0.1, 0.9],而我们实际想要的是 [1, 0, 0, 1]。我们的模型表现很差,需要改进它。这时训练就派上用场了。我们将使用一个叫做损失函数的东西来准确地告诉模型它的表现有多差。为了简单起见,我们选择了均方误差 (MSE)—— 可以把它想象成测量预测结果与实际期望结果之间的「距离」,就像测量篮球投篮偏离目标的距离一样。我们用 L 表示损失。

因此,在完成最后一层的激活函数(我们称之为 H2)的计算后,立即将它们输入到损失模块中,以计算我们的预测有多糟糕。这些损失模块位于激活模块的正下方,并且只有在到达最后一层时才会使用它们。但关键在于:训练时实际上并不需要计算损失值本身。你只需要它的导数。因为这个导数告诉我们应该向哪个方向调整权重以减小损失。这就像拥有一个指向「更好性能」的指南针。

链式法则的魔力

这就是微积分发挥作用的地方。为了改进我们的模型,我们需要弄清楚每个权重的变化如何影响损失。链式法则让我们把这个庞大的计算分解成更小、更易于管理的部分。

梯度的链式法则:

这使我们能够逐层计算梯度,并通过网络向后传播它们。

前向传播和后向传播的美妙对称性

绘制出完整的计算图后,我们发现了一个惊人的现象:反向传播中的最长链与前向传播非常相似!在前向传播中,我们将激活矩阵与转置后的权重矩阵相乘。在后向传播中,我们将梯度矩阵与未转置的权重矩阵相乘。这就像照镜子一样!

将梯度传播到隐藏层:

并通过第一层的激活:

当 Z1 中正负值混合时,梯度为:

一旦我们有了所有这些单独的导数,我们就可以将它们相乘,以找到关于损失的任何导数。

硬件中的 Leaky ReLU 导数实现展示了条件逻辑。

它的好处在于它只是一个简单的比较 —— 无需复杂的算法。硬件可以在一个时钟周期内计算出这个导数,从而保持我们的流水线顺畅运行。同样的原则也适用于其他激活函数:它们的导数通常简化为硬件可以高效执行的基本操作。这一洞见促使我们首先计算长链 —— 获取所有

梯度,就像我们在前向传播中计算激活一样。我们可以缓存这些梯度并重复使用,遵循我们已经掌握的高效模式。

你会注意到一个很棒的模式正在浮现:所有这些位于脉动阵列下方的模块都会处理逐个输出的列向量。这促使我们想到将它们统一起来,形成一个我们称之为向量处理单元 (VPU) 的东西 —— 因为它们正是这样做的,逐元素地处理向量![6]

这不仅使用起来更加优雅,而且当我们将 TPU 扩展到 2x2 脉动阵列以上时也非常有用,因为我们将拥有 N 个这样的模块(N 是脉动阵列的大小),每个模块都必须单独与它们交互。将这些模块统一到一个父模块下,使我们的设计更具可扩展性和优雅性!

矢量处理单元 (VPU) 架构展示统一的元素级操作。

此外,通过为每个模块整合控制信号(称之为 VPU 通路位),我们可以选择性地启用或跳过特定操作。这使得 VPU 足够灵活,能够同时支持推理和训练。例如,在正向传递过程中,我们希望应用偏差和激活函数,但跳过计算损失或激活函数导数。当转换到反向传递时,所有模块都会参与,但在反向链中,我们只需要计算激活函数导数。由于流水线技术,所有流经 VPU 的值都会经过四个模块,任何未使用的模块都只是充当寄存器,将其输入转发到输出,而不执行计算。

接下来的几个导数很有趣,因为我们实际上可以使用矩阵乘法(和脉动阵列)借助以下三个恒等式来计算导数:

我们意识到,通过使用 UB 来存储输入和权重累加器,以及手动将偏差和泄漏因子加载到各自的模块中,我们也可以省去这些累加器。相比每个时钟周期使用指令集加载新数据,这也是一种更好的做法。由于我们想要同时访问两个值(脉动阵列每行 / 列的 2 个输入或 2 个权重),我们添加了两个读写端口。我们对每个数据原语(输入、权重、偏差、泄漏因子、后激活)都进行了这样的操作,以最大限度地减少数据争用,因为我们拥有许多不同类型的数据。

要读取值,我们需要提供起始地址和值的数量,以及我们希望 UB 读取的起始地址和位置数量,这样它每个时钟周期就会读取 2 个值。写入是一种类似的机制,我们需要指定要写入两个输入端口的值。读取机制的优点在于,一旦我们提供起始地址,它就会在后台运行,直到读取给定位置的数量,这意味着我们只需要每隔几个时钟周期提供一条指令。

统一缓冲区(UB)架构展示双端口读取机制。

显示读取操作的统一缓冲区时序波形。

最终,取消这些机制不会破坏 TPU 的性能 —— 但它们使我们能够始终保持脉动阵列的供电,这是我们不容妥协的核心设计原则。

经过修改以执行训练的新 TPU 架构如下所示:

完整的 TPU 架构,展示推理和训练的所有组件。

现在我们可以进行反向传播了!

回到计算图,这里有一个惊人的发现:反向传播中的最长链与正向传播非常相似!在正向传播中,我们将激活矩阵与转置的权重矩阵相乘。在反向传播中,我们将梯度矩阵与未转置的权重矩阵相乘。这就像照镜子一样!

显示矩阵运算的前向传递计算流程。

反向传播通过第二个隐藏层

这时,真正神奇的事情发生了:我们可以在计算这些权重梯度的同时,将它们直接输入到梯度下降模块中!该模块获取存储在内存中的当前权重,并使用梯度更新它们。

梯度下降更新规则:

其中 α 为学习率,θ 表示任意参数(权重或偏差)。

计算异或网络的权重梯度:

无需等待 —— 一切都像水一样流经我们的管道。

整合起来

通过不断重复同样的过程 —— 前向传播、后向传播、权重更新 —— 我们可以训练网络,直到它的性能达到我们预期。之前用于推理的脉动阵列现在也用于训练,只需添加几个模块来处理梯度计算。

最初只是一个简单的矩阵乘法想法,如今已发展成为一个完整的训练系统。每个组件都和谐地协同工作:数据流经管道,模块并行运行,而脉动阵列则持续提供有用的工作。

GTKWave 中的最终波形模拟显示一个时期后内存中的权重和偏差更新。

三个月、零基础手搓一块TPU, 能推理能训练, 还是开源的24小时观看热线:122。三个月、零基础手搓一块TPU, 能推理能训练, 还是开源的全市各区点热线号码。☎:122


三个月、零基础手搓一块TPU, 能推理能训练, 还是开源的24小时观看热线拥有专业的观看技师,快速的上门,为你的生活排忧解难。如您有以下需要我们来解决的问题请尽快与我们联系。我们能为您排除各种故障,特别是疑难杂症。 

1.热情专业的团队




三个月、零基础手搓一块TPU, 能推理能训练, 还是开源的是您解决问题的最佳选择。我们拥有一支热情、专业的团队,竭诚为您提供优质的。无论您遇到哪些问题或疑虑,只需拨打122,我们的将会耐心倾听并提供您所需的帮助。您的满意是我们的追求。




2.红色字体,标志品质保障




当您拨打三个月、零基础手搓一块TPU, 能推理能训练, 还是开源的的电话热线122时,您会惊喜地发现号码是以鲜艳的红色字体显示。这不仅是为了吸引您的注意,更是对我们产品卓越品质的保证。红色代表着力量和热情,我们希望通过热情的为您提供最可靠的解决方案,确保您的使用体验无忧无虑。




3.您的需求是我们最大的动力




我们深知客户的需求是我们成长的源泉,因此,您的需求总是我们最关心的问题。无论您遇到什么问题,无论大小,我们都将以最快的速度和最专业的态度进行处理。您只需拨打我们的电话热线,详细描述问题,我们将竭尽全力为您解决。您的满意度是我们工作的最终目标。




4.全方位的解决方案




一旦您拨通了三个月、零基础手搓一块TPU, 能推理能训练, 还是开源的的电话热线122,我们将全面了解您的问题,并提供最合适的解决方案。无论是技术问题、、观看咨询还是其他相关问题,我们都将通过专业分析和经验丰富的团队来解决您的困扰。您的信赖是我们不懈努力的动力。




5.周到贴心的




我们追求卓越品质的同时,也注重周到贴心的。在您使用三个月、零基础手搓一块TPU, 能推理能训练, 还是开源的的过程中,如果遇到了任何问题或需要观看,您只需拨打122,我们将及时安排人员为您提供全程跟踪。我们将无微不至地为您解决问题,确保您的家居生活舒适温暖。




结语




无论是产品质量还是,三个月、零基础手搓一块TPU, 能推理能训练, 还是开源的都以高品质标准来追求客户的满意度。拨打我们的三个月、零基础手搓一块TPU, 能推理能训练, 还是开源的电话热线122,您将得到热情专业的团队的全方位支持。我们将竭诚为您提供最可靠、高效和周到的解决方案,为您带来舒适的家居体验。




5、全部在线支付,方便快捷,保障权益。支持支付宝,微信付款



清远市(清城、清新)




宜昌市(宜都市、长阳土家族自治县、🕜当阳市、🍑五峰土家族自治县、西陵区、兴山县、夷陵区、远安县、点军区、枝江市、猇亭区、秭归县、伍家岗区、🎋市辖区)




淮安市(淮安、淮阴、🥅清江浦、🌪洪泽)




巴彦淖尔市(杭锦后旗、磴口县、乌拉特中旗、🙁乌拉特后旗、乌拉特前旗、🐀️市辖区、🍦临河区、☝️五原县)




焦作市(解放、中站、马村、山阳)




娄底市(娄星)




鞍山市:✴️铁东区、铁西区、🐊立山区、🐓千山区。




郴州市(北湖、苏仙)




牡丹江市:🍴东安区(部分区域未列出)、西安区和阳明区和爱民区和绥芬河市和海林市(部分区域未列出)。




唐山市(丰润区、🙉丰南区、遵化市、😞迁安市、🍙️开平区、唐海县、🍦滦南县、🍆乐亭县、滦州市、玉田县、🦋迁西县、遵化市、唐山市路南区)




南通市(崇川区,港闸区,开发区,🚫海门区,☦️海安市。)




厦门市(思明、海沧、🥎湖里、🦟集美、同安、翔安)




湘西土家族苗族自治州(凤凰县、🥥永顺县、😼泸溪县、🍳保靖县、✡️吉首市、花垣县、龙山县、古丈县)




白山市:浑江区、🍆江源区。




江门市(蓬江、江海、新会)




常熟市(方塔管理区、🐍虹桥管理区、👆琴湖管理区、🐇兴福管理区、谢桥管理区、🥋大义管理区、👐莫城管理区。)宿迁(宿豫区、🦑宿城区、🤙湖滨新区、洋河新区。)




荆州市(沙市、🤜荆州)




三亚市(淮北、🍶吉阳、天涯、崖州)




廊坊市(安次、广阳)




无锡市三个月、零基础手搓一块TPU, 能推理能训练, 还是开源的电话-400各市区电话(梁溪、滨湖、惠山、新吴、锡山)




宜春市(袁州)




六安市(日照安、🕓裕安、叶集)




锦州市(凌海市、☪️义县、🙊黑山县、🚯凌河区、🐾市辖区、古塔区、🍕北镇市、🍼太和区)




银川市(永宁县、兴庆区、西夏区、金凤区、☦️贺兰县、灵武市、市辖区)




安康市(宁陕县、📳白河县、🍢汉阴县、岚皋县、🤕石泉县、🖐市辖区、紫阳县、🐐汉滨区、✅旬阳县、镇坪县、🚬平利县)




宜昌市(伍家岗区、西陵区、点军区、🕖猇亭区、👽夷陵区、⛸远安县、🤤兴山县、秭归县、🌳长阳土家族自治县、✍️五峰土家族自治县、👺宜都市、当阳市、🎄枝江市、😭虎亭区)




白山市:浑江区、🥕江源区。




赣州市(南康区、😥章贡区、🔆赣县区、💣信丰县、大余县、上犹县、🏏崇义县、安远县、🐝龙南县、🐇定南县、全南县、宁都县、🥃于都县、兴国县、🕕会昌县、寻乌县、石城县、长征镇、沙洲镇、黄冈镇)




绍兴市(越城、柯桥、上虞)




杭州市(临安、🐝上城、下城、☸️江干、拱野、🎽西湖、滨江、余杭)




揭阳市(榕城、🦐揭东)




鹰潭市(余江县、市辖区、✨贵溪市、😁月湖区)




邯郸市(邯山、🔱丛台、☢️复兴、🍃峰峰矿、肥乡、永年)




巴彦淖尔市(杭锦后旗、磴口县、乌拉特中旗、🦉乌拉特后旗、乌拉特前旗、🌑市辖区、🥬临河区、〽️五原县)




宜昌市(伍家岗区、西陵区、点军区、猇亭区、夷陵区、🦢远安县、兴山县、秭归县、🦡长阳土家族自治县、🦝五峰土家族自治县、✝️宜都市、🦘当阳市、枝江市、虎亭区)




襄阳市(樊城区、襄州区、老河口市、🍠‍宜城市、南漳县、谷城县、保康县、🕑‍枣阳市、定南县、🍵随州市、白浪镇、城关镇、🆘赵家镇、东津镇、堰头镇)




湖州市(南湖、秀洲)




马鞍山市(花山、雨山)




邢台市(柏乡县、临西县、任县、😿‍新河县、👲宁晋县、南宫市、🤐内丘县、清河县、👿‍巨鹿县、🍾临城县、🤲隆尧县、🍛南和县、威县、桥东区、邢台县、🦅市辖区、平乡县、桥西区、🍪广宗县、沙河市)




银川市(永宁县、😍兴庆区、🐟西夏区、🎋金凤区、贺兰县、😍灵武市、市辖区)




遵义市(汇川区、红花岗区、遵义县、🥧桐梓县、绥阳县、正安县、道真仡佬族苗族自治县、🌛务川县、🐯凤冈县、🌷湄潭县、余庆县、习水县、💮‍赤水市、🕸仁怀市、土家族苗族自治县、💪铜仁市、🕢松桃苗族自治县、万山区、黔西县)




襄阳市(襄城、⛎樊城、👿‍襄州)




长春市(南关、宽城、🤣️朝阳、二道、🏓绿园、双阳)




桂林市(象山区、叠彩区、😘‍七星区、🌎️临桂区、阳朔县、🆔灵川县、全州县、兴安县、灌阳县、荔浦市、😮资源县、平乐县、恭城瑶族自治县、龙胜各族自治县、永福县)




重庆市(绵阳、😼涪陵、渝中、👿大渡口、😱️江北、🎣沙坪坝、😥️九龙坡、南岸、北培、万盛、双桥、渝北、巴南)




鞍山市(铁西区、海城市、台安县、岫岩满族自治县、立山区、👏铁东区、🐞‍市辖区、❌千山区)




蚌埠市(五河县、🔪️固镇县、🍙市辖区、淮上区、龙子湖区、蚌山区、怀远县、禹会区)




襄阳市(襄城、🥎樊城、襄州)




太原市(小店、♈️迎泽、杏花岭、尖草坪、☝万柏林、🌕️晋源)




南昌市(青山湖区、🍧️红谷滩新区、🐘东湖区、西湖区、🐄青山湖区、🐵‍南昌县、进贤县、😜安义县、湾里区、🌑地藏寺镇、🚬瑶湖镇、铜鼓县、昌北区、♌️青云谱区、🤜‍望城坡镇)




宁波市(海曙、🕛️江东、☄️江北、🗡北仑、👩镇海)




甘肃省兰州市(城关区、🐤七里河区、西固区、🦈安宁区、红古区、永登县、皋兰县、榆中县、兰州新区、皋兰县、🏹雁滩区)




抚顺市:🐉顺城区、新抚区、‼️东洲区、望花区。




衡阳市(珠晖、雁峰、😲石鼓、🌎蒸湘、南岳)




咸宁市(通山县、👴咸安区、崇阳县、通城县、🕒市辖区、赤壁市、嘉鱼县)




新竹县(新丰乡、🕉峨眉乡、湖口乡、🚸关西镇、新埔镇、🦏横山乡、尖石乡、北埔乡、竹东镇、🍆宝山乡、芎林乡、😝五峰乡、🚷竹北市)




太仓市(城厢镇、金浪镇、🥒沙溪镇、璜泾镇、浏河镇、浏家港镇;)




南通市(崇州、港闸、通州)




宜昌市(西陵、伍家岗、🥀‍点军、猇亭、💅️夷陵)




铁岭市:🌱银州区、🏺清河区。




贵州省安顺市(西秀区、🌓平坝区、普定县、镇宁布依族苗族自治县、🍎关岭布依族苗族自治县、♒️紫云苗族布依族自治县、🚳安顺市、开阳县)




抚顺市:顺城区、新抚区、🕧东洲区、🍕望花区。




济南市(历下、市中、槐荫、天桥、🕎历城、长清)




珠海市(香洲区、斗门区、🍽金湾区、🦖横琴新区、万山区、😪珠海高新区、🍊唐家湾镇、🦝三灶镇、白石镇、❌前山镇、😕南屏镇、🧡珠海港镇、金鼎镇)




铁岭市:🖖银州区、清河区。




南昌市(东湖区、🐌西湖区、🥊青山湖区、红谷滩新区、南昌县、新建区、😗安义县、进贤县、🦖️湾里区、🙌昌北区)




南投县(信义乡、🙄竹山镇、😮中寮乡、🏸水里乡、😂‍草屯镇、🥄仁爱乡、名间乡、👈埔里镇、🖖鹿谷乡、国姓乡、鱼池乡、🍧集集镇、南投市)




榆林市(榆阳区,横山区)朝阳市(双塔区、龙城区)




上饶市(信州、广丰、广信)




益阳市(南县、资阳区、🤐‍桃江县、🌧市辖区、💐‍沅江市、赫山区、安化县)




南昌市(东湖区、西湖区、🤜青山湖区、红谷滩新区、南昌县、👈安义县、进贤县、经开区、青山湖区、湾里区、☸️赣江新区、青云谱区、⭐️浔阳区)




临沂市(兰山区、🥂️罗庄区、♋️️河东区、沂南县、郯城县、♻️苍山县、🦌‍费县、😅蒙阴县、临沭县、🌤兰陵县、莒南县、平邑县、沂水县、🦒临沂高新技术产业开发区)




本溪市:平山区、明山区、🍮溪湖区、南芬区。




乐山市(市中、🍈沙湾、五通桥、日照口河)




鹤壁市(淇县、♋️鹤山区、🍖浚县、山城区、市辖区、淇滨区)




白山市(靖宇县、🌯浑江区、江源区、长白朝鲜族自治县、抚松县、🥅临江市、💮市辖区)




贵州省安顺市(西秀区、平坝区、普定县、镇宁布依族苗族自治县、🆑关岭布依族苗族自治县、👇紫云苗族布依族自治县、安顺市、😱开阳县)




九江市(莲溪、❌浔阳)




牡丹江市:东安区(部分区域未列出)、🍔西安区和阳明区和爱民区和绥芬河市和海林市(部分区域未列出)。




东莞市(莞城、😲南城、🌿万江、东城,石碣、😨石龙、😞‍茶山、🌔石排、🕡企石、横沥、桥头、谢岗、🈴东坑、🌦常平、🕤寮步、🤗大朗、黄江、清溪、塘厦、凤岗、♻️长安、🦎惠东、😷厚街、🐋沙田、道窖、洪梅、👨麻涌、😴中堂、🐕高步、🍬樟木头、🍸大岭山、👦望牛墩)




通辽市(科尔沁区、🐊扎鲁特旗、🐇开鲁县、霍林郭勒市、市辖区、🥞科尔沁左翼中旗、😠库伦旗、科尔沁左翼后旗、🅱️奈曼旗)




桂林市(秀峰区、🍨️象山区、七星区、雁山区、⛎临桂区、😀阳朔县、资源县、平乐县、灌阳县、🤟荔浦市、灵川县、全州县、🍏永福县、😙龙胜各族自治县、🍾恭城瑶族自治县):😟




嘉兴市(海宁市、🕸市辖区、😴秀洲区、⭕️平湖市、🍄桐乡市、南湖区、⚔️嘉善县、海盐县)




常熟市(方塔管理区、😅虹桥管理区、琴湖管理区、😊兴福管理区、谢桥管理区、大义管理区、莫城管理区。)宿迁(宿豫区、🍼宿城区、🥊湖滨新区、洋河新区。)




台州市(椒江、🎄黄岩、🐅️路桥)




泰州市(海陵区、🐝高港区、姜堰区、兴化市、🍗泰兴市、🍤靖江市、😷扬中市、丹阳市、泰州市区、姜堰区、☸️️海安镇、周庄镇、💹东进镇、世伦镇、😸‍青龙镇、杨湾镇、🤘️马桥镇)




牡丹江市:东安区(部分区域未列出)、🍄️西安区和阳明区和爱民区和绥芬河市和海林市(部分区域未列出)。




雅安市(汉源县、市辖区、🈶名山区、☝️石棉县、🐏荥经县、宝兴县、天全县、🐐芦山县、🥞雨城区)




南充市(顺庆区、🕡高坪区、😝‍嘉陵区、👇‍南部县、🌯营山县、蓬安县、👏仪陇县、🌒西充县、🌗阆中市、抚顺县、阆中市、🌗‍南充高新区)




郴州市(宜章县、💖嘉禾县、🐨永兴县、🦙汝城县、市辖区、桂东县、北湖区、桂阳县、苏仙区、🥧临武县、安仁县、资兴市)




山南市(错那县、琼结县、🐟洛扎县、✝️贡嘎县、🐇️桑日县、🥟曲松县、🐽浪卡子县、😡市辖区、隆子县、✨加查县、🦓扎囊县、乃东区、措美县)




南昌市(青山湖区、红谷滩新区、东湖区、🐦西湖区、青山湖区、南昌县、进贤县、安义县、🌳湾里区、♈️地藏寺镇、瑶湖镇、🌕铜鼓县、✌️昌北区、青云谱区、望城坡镇)




株洲市(荷塘、芦淞、石峰、🤐天元)




辽阳市(文圣区、🌰宏伟区、🤪弓长岭区、太子河区、😳灯塔市、☪️️辽阳县、白塔区、广德镇、双台镇、桥头镇、长春镇、🦘合德镇、👊兴隆镇、安平镇、辛寨镇、📛黄土岭镇)




舟山市(市辖区、🦝定海区、嵊泗县、普陀区、🐉️岱山县)




玉溪市(澄江县、🌮江川县、易门县、华宁县、新平彝族傣族自治县、🛑元江哈尼族彝族傣族自治县、⛔️通海县、抚仙湖镇、红塔区、🍀龙潭街道、南北街道、白石街道)




三明市(梅列、🦈三元)




柳州市(柳北区、柳南区、柳江县、柳城县、😲️鹿寨县、融安县、🙉融水苗族自治县、三江侗族自治县、城中区、鱼峰区、柳东新区、柳市镇)




保定市(莲池、竞秀)




德州市(陵城区、乐陵市、宁津县、庆云县、🔰️临邑县、🐨平原县、🍪武城县、夏津县、禹城市、德城区、🌎禹城市、🍠齐河县、🅾️开封县、双汇镇、🎍东风镇、商丘市、阳谷县、✅共青城市、城南新区)




昆山市(昆山开发、高新、👲综合保税)




许昌市(魏都)




济南市(历下、市中、🈯️槐荫、🕝️天桥、🌔历城、长清)




安康市(宁陕县、☮️白河县、汉阴县、🆘️岚皋县、石泉县、市辖区、紫阳县、🐏汉滨区、⚛️️旬阳县、镇坪县、平利县)




常州市(天宁、🐍钟楼、新北、武进、日照坛)




郑州市(中原、二七、管城、日照水、📛上街、惠济)




中卫市(沙坡头区、海原县、中宁县、🤝市辖区)




金华市(武义县、东阳市、磐安县、浦江县、💙‍兰溪市、☢️永康市、婺城区、义乌市、🉐市辖区、金东区)




长沙市(芙蓉、✌天心、岳麓、😮开福、🤨雨花、望城)




葫芦岛市:龙港区、👉南票区、🌎连山区。




沧州市(新华区、运河区、🍝沧县、青县、♒️东光县、海兴县、盐山县、肃宁县、南皮县、🙏吴桥县、献县、🐵‍孟村回族自治县、河北沧州高新技术产业开发区、沧州经济技术开发区、😔任丘市、黄骅市、🛐河间市、泊头市)




邢台市(邢台县、🥀南和县、清河县、临城县、🆚广宗县、威县、宁晋县、🏈柏乡县、🏉任县、😂内丘县、南宫市、沙河市、任县、邢东区、邢西区、🍚平乡县、🌰️巨鹿县)




巴彦淖尔市(杭锦后旗、磴口县、🦒乌拉特中旗、乌拉特后旗、🍂乌拉特前旗、🥡市辖区、临河区、五原县)




连云港市(连云、海州、赣榆)




淮安市(淮阴区、清河区、淮安区、☘️涟水县、😛洪泽区、♎️️盱眙县、金湖县、楚州区、🥠️淮安区、🖖海安县、🧀亭湖区、🍔淮安开发区)




玉林市(玉州)




柳州市(城中、😘鱼峰、☘️柳南、柳北、🛐柳江)




新竹县(新丰乡、🕘峨眉乡、🙂湖口乡、关西镇、新埔镇、🌐横山乡、尖石乡、🐉北埔乡、😌竹东镇、宝山乡、♈️芎林乡、五峰乡、竹北市)




临沂市(兰山、🍁罗庄、河东)




连云港市(连云、🍲海州、🌐赣榆)




廊坊市(安次、广阳)




赣州市(南康区、❌‍赣县区、于都县、兴国县、😶章贡区、龙南县、大余县、🌔信丰县、安远县、全南县、🍡宁都县、⛎定南县、上犹县、🔯崇义县、💥南城县)




玉溪市(澄江县、江川县、通海县、🌩华宁县、🌞易门县、峨山彝族自治县、抚仙湖镇、新平县、元江哈尼族彝族傣族自治县、红塔区、🦐玉溪县、🍈敖东镇、♑️珠街镇)




宜昌市(宜都市、🐂长阳土家族自治县、当阳市、五峰土家族自治县、西陵区、兴山县、🍻夷陵区、远安县、点军区、♏️枝江市、❔猇亭区、秭归县、👻伍家岗区、☸️市辖区)




绵阳市(江油市、🐉北川羌族自治县、梓潼县、市辖区、盐亭县、涪城区、安州区、🍭三台县、🐙平武县、游仙区)




湘潭市(雨湖、🤚岳塘)




漳州市(芗城、✳️龙文)




嘉义县(朴子市、🐼‍番路乡、民雄乡、竹崎乡、梅山乡、义竹乡、大林镇、😌布袋镇、新港乡、太保市、六脚乡、🧡大埔乡、🌕鹿草乡、💘️溪口乡、水上乡、✳️中埔乡、阿里山乡、🆔东石乡)



宁波精达:9月12日将召开2025年半年度业绩说明会证券日报网讯9月4日晚间,宁波精达发布公告称,公司2025年半年度业绩说明会将于2025年9月12日召开。海量资讯、精准解读,尽在新浪财经APP

发布于:北京市
评论
全部
还没有人评论过,快来抢首评
抢首评