DeepSeek-Coder-V2 教程:示例、安装、基准

推荐指数

本文最后由 Demo Marco 更新于 2025-02-22. 如有资源已失效,请留言反馈,将会及时处理。 【推荐:不翻墙访问被墙网站方法 | 自用高速专线机场 | 高速CN2线路 | 高质量家宽住宅IP

随着GitHub Copilot等人工智能编码助手在开发人员中越来越受欢迎,开源替代品也不断涌现。

一个值得注意的例子是DeepSeek-Coder-V2 ,这是一个利用先进机器学习技术的强大开源模型。它专为与代码相关的任务而设计,在代码生成、完成和理解方面提供与GPT-4相当的性能。

在本文中,我将解释 DeepSeek-Coder-V2 的特性和功能,并指导您如何开始使用此工具。

什么是 DeepSeek-Coder-V2?

DeepSeek-Coder-V2 是一个开源混合专家 (MoE)代码语言模型,在代码特定任务上的性能可与 GPT-4 相媲美。该模型旨在帮助开发人员,它带来了几个关键功能:

  • 多语言:使用多种语言(包括英语和中文)的代码和自然语言进行训练,使其能够适用于全球开发团队。
  • 多功能:支持超过 338 种编程语言,满足不同的编码环境和需求。
  • 大规模:对数万亿个代码和文本数据进行预训练,增强其在各种编码场景中的理解和生成能力。
  • 多种尺寸:模型有多种尺寸可供选择,允许开发人员选择最适合其计算资源和项目要求的模型尺寸。

您可以在DeepSeek 的网站上访问该模型,他们提供付费 API 访问和聊天。源代码可在GitHub上获取,研究论文托管在arXiv上。

这些模型托管在Huggingface上——但是,由于模型的大小,您需要研究级硬件才能在本地运行这些模型。

DeepSeek-Coder-V2 基准

让我们看看 DeepSeek-Coder-V2 在基准测试中的表现如何,以及与 GPT-4 Turbo、 Gemini 1.5 Pro、Claude 3 Opus、LLaMA 3-70B和Codestral等模型的比较情况。

来源:朱启豪等

人力评估

HumanEval 基准通过评估生成的代码是否通过特定的单元测试来衡量代码生成能力。DeepSeek-Coder-V2 在该基准上表现出色,准确率达到 90.2%。这一结果凸显了该模型即使在复杂场景中也能生成功能齐全且准确的代码片段的能力。

骨髓移植+

MBPP+ 基准测试侧重于代码理解,评估模型理解和解释代码结构和语义的能力。DeepSeek-Coder-V2 再次在这一领域表现出色,准确率达到 76.2%,凸显了其对代码含义和功能的强大把握。

数学

MATH 基准测试模型在代码中的数学推理能力。DeepSeek-Coder-V2 以 75.7% 的准确率保持领先,表明其能够熟练处理代码中嵌入的数学运算和逻辑,这是许多编程任务的关键方面。

GSM8K

GSM8K 基准测试专注于解决小学数学应用题,评估模型除纯代码生成之外的更广泛的问题解决能力。DeepSeek-Coder-V2 的准确率仅次于 Claude 3 Opus,为 94.9%,证明了其理解和解决自然语言中提出的数学问题的能力。

艾德

Aider 基准测试评估了模型提供代码帮助和建议的能力。DeepSeek-Coder-V2 以 73.7% 的准确率领先,这表明它有可能成为开发人员在编码任务期间寻求实时指导和支持的宝贵工具。

活码测试

LiveCodeBench 基准测试了实际场景中的代码生成性能。DeepSeek-Coder-V2 的准确率达到了 43.4%(仅次于 GPT-4-Turbo-0409),展示了其在实际环境中生成实用且可用代码的能力。

SWE Bench 基准

​​SWE-Bench 基准专门评估 AI 模型执行软件工程任务的能力,例如代码生成、调试和理解复杂的编程概念。在此背景下,DeepSeek-Coder-V2 获得了 12.7 分,表明其表现稳健但并非领先。它落后于 GPT-4-Turbo-0409(18.7)和 Gemini-1.5-Pro(18.3),这些模型在这些任务中表现出色。然而,DeepSeek-Coder-V2 的表现仍然优于 Claude-3-Opus(11.7)、Llama-3-70B(2.7)和 Codestral 等模型,这表明基于此基准,它是软件工程应用的可靠但不是顶级选择。

DeepSeek-Coder-V2 的工作原理

DeepSeek-Coder-V2 以 DeepSeek-V2 模型为基础,利用复杂的混合专家 (MoE) 架构在特定代码任务中实现高性能。该模型利用多个专家模型,每个模型专门处理不同的编码任务,并根据输入代码动态选择最相关的专家。这种方法提高了模型的效率和准确性。

DeepSeek-Coder-V2 的训练过程涉及几个关键部分。它在一个综合数据集上进行了预训练,该数据集由 60% 的源代码、10% 的数学语料库和 30% 的自然语言语料库组成,总计 10.2 万亿个 token。这个多样化的数据集使模型能够有效地理解和生成代码。源代码数据集包括来自 GitHub 和 CommonCrawl 的 1,1700 亿个 token,涵盖 338 种编程语言,与以前的模型相比有了显著的扩展。

经过预训练后,该模型将使用包含编码、数学和通用语言指令的专门指令数据集进行微调。此过程可提高模型对自然语言提示的响应能力,从而将模型转变为有用的助手。

对于那些对底层架构感兴趣的人,DeepSeek-Coder-V2 所基于的 DeepSeek-V2 模型引入了多头潜在注意力 (MLA) 和 DeepSeekMoE 框架等创新。这些创新有助于实现高效推理和经济训练,详情可参见arXiv上的 DeepSeek-V2 论文。

DeepSeek-Coder-V2 入门

有几种方法可以开始使用 DeepSeek-Coder-V2 模型。您可以通过Hugging Face 的transformers访问该模型,在本地运行该模型。但是,请注意,这些模型相当大,需要大量的计算资源。

另外,DeepSeek 提供付费 API 和类似于 ChatGPT 的在线聊天界面。DeepSeek 的在线聊天还可以直接在聊天窗口中运行 HTML 和 JavaScript 代码!此功能非常创新 – 我只在Claude 3.5 Sonnet模型的Artifacts中看到过类似的东西。在本文中,我们将使用聊天功能作为示例。

DeepSeek-Coder-V2:使用示例

对于第一个例子,我将要求模型使用 HTML 和 JavaScript 编写康威生命游戏。我向模型提出了以下提示:“你能用 HTML 编写康威生命游戏吗?”以下是响应:

Certainly! Below is a simple implementation of Conway's Game of Life using HTML, CSS, and JavaScript. This version will display the grid in an HTML table and update it every second.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Conway's Game of Life</title>
<style>
table {
border-collapse: collapse;
}
td {
width: 10px;
height: 10px;
border: 1px solid #ccc;
}
.alive {
background-color: black;
}
.dead {
background-color: white;
}
</style>
</head>
<body>
<h1>Conway's Game of Life</h1>
<table id="grid"></table>
<script>
const N = 50; // Grid size
let grid = createGrid(N);
let intervalId;
function createGrid(N) {
let grid = new Array(N);
for (let i = 0; i < N; i++) {
grid[i] = new Array(N);
for (let j = 0; j < N; j++) {
grid[i][j] = Math.random() > 0.7 ? 1 : 0;
}
}
return grid;
}
function renderGrid(grid) {
const table = document.getElementById('grid');
table.innerHTML = '';
for (let i = 0; i < N; i++) {
const row = table.insertRow();
for (let j = 0; j < N; j++) {
const cell = row.insertCell();
cell.classList.add(grid[i][j] ? 'alive' : 'dead');
}
}
}
function updateGrid(grid) {
const newGrid = grid.map(row => row.slice());
for (let i = 0; i < N; i++) {
for (let j = 0; j < N; j++) {
const aliveNeighbors = countAliveNeighbors(grid, i, j);
if (grid[i][j] === 1) {
newGrid[i][j] = aliveNeighbors === 2 || aliveNeighbors === 3 ? 1 : 0;
} else {
newGrid[i][j] = aliveNeighbors === 3 ? 1 : 0;
}
}
}
return newGrid;
}
function countAliveNeighbors(grid, x, y) {
let count = 0;
for (let i = -1; i <= 1; i++) {
for (let j = -1; j <= 1; j++) {
if (i === 0 && j === 0) continue;
const newX = (x + i + N) % N;
const newY = (y + j + N) % N;
count += grid[newX][newY];
}
}
return count;
}
function startGame() {
intervalId = setInterval(() => {
grid = updateGrid(grid);
renderGrid(grid);
}, 1000);
}
renderGrid(grid);
startGame();
</script>
</body>
</html>

我们还可以点击响应末尾的“运行 HTML”按钮,直接在我们的聊天窗口中获取生命游戏。

截图由作者提供。

接下来,我让模型制作一个动态的游戏网站,我可以在网站上选择起始板配置。结果就是这样,而且运行得相当完美。

截图由作者提供。

对于我们的最后一个例子,我在一个困难的欧拉计划问题上测试了该模型—— “跳蛙”问题。以下是该模型生成的代码:

import numpy as np

MOD = 10**9


def matrix_power(matrix, n):
result = np.identity(len(matrix), dtype=int)

while n > 0:
if n % 2 == 1:
result = np.dot(result, matrix) % MOD

matrix = np.dot(matrix, matrix) % MOD
n //= 2

return result


def fib_matrix(n):
if n == 0:
return 0
elif n == 1:
return 1

A = np.array([[1, 1, 1], [1, 0, 0], [0, 1, 0]], dtype=int)
A_power = matrix_power(A, n - 3)
initial_vector = np.array([2, 1, 1])

return np.dot(A_power, initial_vector)[0] % MOD


def S(L):
result = 0

for n in range(1, L + 1):
f_n = fib_matrix(n)
result = (result + f_n**3) % MOD

return result


# Compute S(10**14) % 10**9
print(S(10**14))

这个脚本需要很长时间才能运行,所以我要求模型对其进行优化并得到以下输出:

import numpy as np

MOD = 10**9


def matrix_power(matrix, n):
result = np.identity(len(matrix), dtype=int)

while n > 0:
if n % 2 == 1:
result = np.dot(result, matrix) % MOD
matrix = np.dot(matrix, matrix) % MOD
n //= 2

return result


def fib_matrix(n):
if n == 0:
return 0
elif n == 1:
return 1

A = np.array([[1, 1, 1], [1, 0, 0], [0, 1, 0]], dtype=int)
A_power = matrix_power(A, n - 3)
initial_vector = np.array([2, 1, 1])

return np.dot(A_power, initial_vector)[0] % MOD


def find_pisano_period(m):
previous, current = 0, 1
for i in range(m * m):
previous, current = current, (previous + current) % m
if previous == 0 and current == 1:
return i + 1


def S(L):
pisano_period = find_pisano_period(MOD)
period_sum = 0

for n in range(1, pisano_period + 1):
f_n = fib_matrix(n)
period_sum = (period_sum + f_n**3) % MOD

full_periods, remainder = divmod(L, pisano_period)
result = (full_periods * period_sum) % MOD

for n in range(1, remainder + 1):
f_n = fib_matrix(n)
result = (result + f_n**3) % MOD

return result


# Compute S(10**14) % 10**9
print(S(10**14))

我让优化后的代码运行了半个小时,但仍然没有产生结果。虽然我认为解决方案是正确的,但挑战在于优化代码。考虑到只有 328 人成功解决了这个问题,模型无法解决它也就不足为奇了。

结论

DeepSeek-Coder-V2 是不断发展的开源编码助手领域的一个显著补充,其性能与成熟的专有模型相比具有竞争力。

为了充分利用 DeepSeek-Coder-V2,请遵循最佳实践,提供清晰、具体的提示。如果您遇到任何错误,我也鼓励您向开发人员提供反馈。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

You May Also Like