首页
/ generative-ai-for-beginners 第 20 课实战:Mistral Large / Small / NeMo 三款模型的选型与代码示例全解析

generative-ai-for-beginners 第 20 课实战:Mistral Large / Small / NeMo 三款模型的选型与代码示例全解析

2026-09-07 23:44:13作者:郦嵘贵Just

本篇文章完整拆解开源课程 generative-ai-for-beginners 中"使用 Mistral 模型构建应用"(Building with Mistral Models)一课的全部知识点与可运行代码。你将掌握 Mistral 家族中 Mistral Large 2、Mistral Small、Mistral NeMo 三款模型的定位差异、适用场景与调用方式,并通过本仓库附带的 Jupyter Notebook 示例,亲手跑通基于 faiss 的 RAG 检索增强生成、小/大模型延迟对比、Tekken 与 tiktoken 分词效率对比三组实验。本文以 translations/da/20-mistral/README.md(课程丹麦语译本)为讲解主线,并同步对照仓库中最新英文原版 20-mistral/README.md 与可直接运行的 Notebook 20-mistral/python/githubmodels-assignment.ipynb 进行深化解读。

本节课程概览:要探索什么

第 20 课是整个 21 课课程体系中的一个独立专题(课程大纲见根目录 README.md),面向已具备基础提示词与生成式 AI 概念的开发者。本课要解决的问题非常聚焦:当供应商(Mistral)同时提供多款模型时,究竟该选哪一款,以及每款模型独有的能力如何落地到代码里。

原文档在"Introduction"(Introduktion)一节给出的学习目标是:

  • 探索不同的 Mistral 模型;
  • 理解每款模型各自的使用场景(use-cases)与适用条件;
  • 通过代码示例观察每款模型的独有特性。

课程选择的对比对象是三款风格差异明显的模型:Mistral Large(旗舰级、偏企业应用)、Mistral Small(小语言模型、低成本低延迟)与 Mistral NeMo(开源 Apache-2.0 模型、面向可本地化与微调场景)。三款模型并列讲解,恰好对应课程主线中 LLM 选型、SLM、函数调用、微调等多个横向主题的交叉点。

运行前提:模型从哪来、凭据如何配置

按丹麦语译本中的说明,这三款模型都可以在 GitHub Model Marketplace(对应英文新版中已迁移至 Microsoft Foundry Models)免费获取,课程 Notebook 直接以这些在线模型作为推理后端。从当前仓库可以看到模型市场的演进痕迹:

  • 丹麦语译本 translations/da/20-mistral/README.md 的代码快照仍使用硬编码 endpoint https://models.inference.ai.azure.com 并从环境变量读取 GITHUB_TOKEN
  • 而仓库主 README 与 20-mistral/README.md 均标注:GitHub Models 将于 2026 年 7 月底退役,官方推荐改用 Microsoft Foundry Models 的模型推理服务,即从 Microsoft Foundry 项目的 Overview 页面获取 AZURE_INFERENCE_ENDPOINTAZURE_INFERENCE_CREDENTIAL 两个环境变量。

因此,如果你的代码运行在今天的环境,建议按新版 Notebook 的写法配置两个环境变量;若沿用旧版(GitHub Models),则把 endpoint 写成 models.inference.ai.azure.com、token 从 GITHUB_TOKEN 读取。仓库中的环境变量工程实践可以参考 shared/python/env_utils.py 中安全读取密钥的写法,以及课程第 00 课的供应商对比说明 00-course-setup/03-providers.md。完整的本地开发环境搭建方式见 00-course-setup/02-setup-local.md

代码统一通过 Azure AI Inference SDK(azure-ai-inference)访问模型:聊天补全使用 ChatCompletionsClient,向量化使用 EmbeddingsClient。这一客户端模式与课程中其他"assignment"作业保持一致,例如 06-text-generation-apps/python/githubmodels-app.py 中也是相同风格的封装。

Mistral Large 2 (2407):面向企业的旗舰模型

Mistral Large 2 是 Mistral 当前的旗舰模型,设计目标就是企业级应用。按原文档,它是初代 Mistral Large 的升级版,主要提升体现在三方面:

能力维度 Mistral Large 2 原版 Mistral Large
上下文窗口 128k 32k
数学与代码任务平均准确率 76.9% 60.4%
多语言 英语、法语、德语、西班牙语、意大利语、葡萄牙语、荷兰语、俄语、中文、日语、韩语、阿拉伯语、印地语 ——

这些指标与语言列表均出自课程文档原文,用于说明"旗舰"定位而非营销表述。基于更大的上下文窗口与更强的代码能力,原文档总结 Mistral Large 2 最擅长以下三类任务:

  • 检索增强生成(RAG)——得益于更大的 128k 上下文窗口,可以把大段检索到的资料拼进提示词中一并推理;
  • 函数调用(Function Calling)——模型原生支持函数调用,可与外部工具和 API 集成,调用既可以并行(parallel)发出,也可以按顺序逐个完成;
  • 代码生成——在 Python、Java、TypeScript、C++ 代码生成上表现突出。

其中"更大的上下文窗口正是 RAG 的理想宿主"这一设计逻辑,可与本课程第 15 课 15-rag-and-vector-databases/README.md 中关于 RAG 原理与向量数据库的讲解互相印证。

实战:用 Mistral Large 2 跑通一个完整 RAG 流程

原文档给出的 RAG 示例非常完整,它是把"向量检索 + 大模型生成"拼成一个最小可用流水线的绝佳范本。整个流程如下:

  1. requests 下载一篇英文长文(Paul Graham 的自述文章);
  2. 2048 字符切块(chunking),得到文本片段列表;
  3. 用 Cohere 的 cohere-embed-v3-multilingual 多语言向量模型把每个片段转成 embedding;
  4. faissIndexFlatL2(欧氏距离暴力检索索引)作为内存向量库,把所有片段向量加入索引;
  5. 用户用韩语提问("作者上大学前主要做的两件事是什么?"),将问题同样向量化后,以 k=2 召回最相似的两个片段;
  6. 把"召回片段 + 问题"拼进一段带约束的提示词,交给 Mistral Large 2 生成自然语言答案。

先安装向量检索依赖:

pip install faiss-cpu

备注:Notebook 输出显示实际安装版本为 faiss-cpu 1.8.0.post1,依赖 numpy<2.0,>=1.0,Python 运行环境为 3.12。若在 Jupyter 内核中安装新包,注意按提示重启内核。

完整代码(与仓库 Notebook 同步):

import requests
import numpy as np
import faiss
import os

from azure.ai.inference import ChatCompletionsClient
from azure.ai.inference.models import SystemMessage, UserMessage
from azure.core.credentials import AzureKeyCredential
from azure.ai.inference import EmbeddingsClient

# Get these from your Microsoft Foundry project's "Overview" page
endpoint = os.environ["AZURE_INFERENCE_ENDPOINT"]
model_name = "Mistral-large"
token = os.environ["AZURE_INFERENCE_CREDENTIAL"]

client = ChatCompletionsClient(
    endpoint=endpoint,
    credential=AzureKeyCredential(token),
)

response = requests.get('https://raw.githubusercontent.com/run-llama/llama_index/main/docs/docs/examples/data/paul_graham/paul_graham_essay.txt')
text = response.text

chunk_size = 2048
chunks = [text[i:i + chunk_size] for i in range(0, len(text), chunk_size)]
len(chunks)

embed_model_name = "cohere-embed-v3-multilingual"

embed_client = EmbeddingsClient(
        endpoint=endpoint,
        credential=AzureKeyCredential(token)
)

embed_response = embed_client.embed(
    input=chunks,
    model=embed_model_name
)



text_embeddings = []
for item in embed_response.data:
    length = len(item.embedding)
    text_embeddings.append(item.embedding)
text_embeddings = np.array(text_embeddings)


d = text_embeddings.shape[1]
index = faiss.IndexFlatL2(d)
index.add(text_embeddings)

question = "저자가 대학에 오기 전에 주로 했던 두 가지 일은 무엇이었나요?"

question_embedding = embed_client.embed(
    input=[question],
    model=embed_model_name
)

question_embeddings = np.array(question_embedding.data[0].embedding)


D, I = index.search(question_embeddings.reshape(1, -1), k=2) # distance, index
retrieved_chunks = [chunks[i] for i in I.tolist()[0]]

prompt = f"""
Context information is below.
---------------------
{retrieved_chunks}
---------------------
Given the context information and not prior knowledge, answer the query.
Query: {question}
Answer:
"""


chat_response = client.complete(
    messages=[
        SystemMessage(content="You are a helpful assistant."),
        UserMessage(content=prompt),
    ],
    temperature=1.0,
    top_p=1.0,
    max_tokens=1000,
    model=model_name
)

print(chat_response.choices[0].message.content)

代码要点逐段解读

  • 切块长度chunk_size = 2048 按字符切割。文档越长的段落越能塞进 128k 上下文,这里为了演示召回逻辑采用相对粗粒度的等长切块;
  • 向量维度对齐d = text_embeddings.shape[1] 从真实 embedding 数组推断维度,再据此实例化 faiss.IndexFlatL2(d),避免硬编码维度导致维度不匹配;
  • 召回index.search(question_embeddings.reshape(1, -1), k=2) 返回 (D, I),其中 D 为距离、I 为命中的片段下标;retrieved_chunks 就是被召回的两个原文片段;
  • 提示词约束:提示词明确要求"仅依据上下文信息回答、不要依赖先验知识"(Given the context information and not prior knowledge),这是 RAG 提示词的标准写法,可以显著降低模型"想当然"生成答案的风险;
  • 生成参数temperature=1.0top_p=1.0 表示保留较大随机性,max_tokens=1000 限制输出长度;model="Mistral-large" 指定模型。实践中做事实性问答往往会把 temperature 调低以提升稳定性。

在仓库 Notebook 的已执行输出中可以看到该示例的真实运行结果——模型用英文正确回答了韩语问题,指出作者上大学前主要从事的两项活动是写作编程,并补充了关于在 IBM 1401 上使用早期 Fortran 编写程序的细节。这证明:即使查询是韩语、召回的是英文原文,多语言 embedding 模型与 Mistral Large 2 的组合也能给出合理回答,这正是本示例选择 cohere-embed-v3-multilingual 的原因。

Mistral Small:主打成本与延迟的小语言模型

Mistral Small 属于 Mistral 家族中 premier/enterprise 分类下的另一款模型。顾名思义,它是一款 Small Language Model(SLM)。围绕 SLM 的价值主张,本课程第 19 课 19-slm/README.md 有专门讨论,可在读完本节后对照学习。

原文档总结了使用 Mistral Small 的三大优点:

  • 成本节省——相比 Mistral Large、NeMo 等大模型,价格下降约 80%
  • 低延迟——相比 Mistral 的大模型响应更快;
  • 灵活——可以部署在多种环境,对算力资源的要求更低、限制更少。

对应的最佳使用场景是:

  • 文本类任务:摘要(summarization)、情感分析(sentiment analysis)、翻译(translation);
  • 需要高频发起请求的应用(得益于其成本效益);
  • 低延迟代码类任务,如代码审查与代码补全建议。

这些场景共同点是"调用频繁"或"对响应速度敏感",因此用更小、更便宜的模型换取吞吐与延迟收益,是典型的工程取舍。

对照实验:同一提示词下对比 Small 与 Large 的延迟

为了直观展示 Mistral Small 与 Mistral Large 在延迟上的差异,原文档要求对两个模型发送完全相同的提示词并观察响应。按文档说明,两个模型的响应时间差应在 3~5 秒左右;同时值得留意的是,面对同一提示词,两者返回的回答长度与风格也不相同。

两个模型各自独立创建 ChatCompletionsClient,仅 model_name 不同,其余调用参数完全一致。首先是用 Mistral Small 生成 FizzBuzz 函数:


import os
endpoint = os.environ["AZURE_INFERENCE_ENDPOINT"]
model_name = "Mistral-small"
token = os.environ["AZURE_INFERENCE_CREDENTIAL"]

client = ChatCompletionsClient(
    endpoint=endpoint,
    credential=AzureKeyCredential(token),
)

response = client.complete(
    messages=[
        SystemMessage(content="You are a helpful coding assistant."),
        UserMessage(content="Can you write a Python function to the fizz buzz test?"),
    ],
    temperature=1.0,
    top_p=1.0,
    max_tokens=1000,
    model=model_name
)

print(response.choices[0].message.content)

再切换到 Mistral Large:


import os
from azure.ai.inference import ChatCompletionsClient
from azure.ai.inference.models import SystemMessage, UserMessage
from azure.core.credentials import AzureKeyCredential

endpoint = os.environ["AZURE_INFERENCE_ENDPOINT"]
model_name = "Mistral-large"
token = os.environ["AZURE_INFERENCE_CREDENTIAL"]

client = ChatCompletionsClient(
    endpoint=endpoint,
    credential=AzureKeyCredential(token),
)

response = client.complete(
    messages=[
        SystemMessage(content="You are a helpful coding assistant."),
        UserMessage(content="Can you write a Python function to the fizz buzz test?"),
    ],
    temperature=1.0,
    top_p=1.0,
    max_tokens=1000,
    model=model_name
)

print(response.choices[0].message.content)

注意,若沿用丹麦语译本对应的旧版配置,需把两处 endpoint/token 替换为 endpoint = "https://models.inference.ai.azure.com"token = os.environ["GITHUB_TOKEN"]。建议在终端分别计时执行两段代码,把"实测延迟差异"作为选型依据之一:如果应用对延迟不敏感,Large 在复杂推理上可能更稳;如果是高频低价值请求,Small 显然更合适。

Mistral NeMo:唯一的 Apache-2.0 开源选项

相比前两款模型,Mistral NeMo 最突出的区别是:它是本课三款模型中唯一采用 Apache-2.0 许可证、可免费使用的模型,被看作是 Mistral 早期开源 LLM Mistral 7B 的升级版。其核心特性有三点:

  • 更高效的分词(tokenization):NeMo 采用 Tekken 分词器,而非更常见的 tiktoken,因此在更多语言与代码上的分词表现更好(即同样的文本能拆出更少的 token,从而降低推理成本、扩大有效上下文);
  • 可微调(finetuning):基础模型开放给开发者微调,为需要定制行为的场景提供了更大灵活性(可对照第 18 课 18-fine-tuning/README.md 了解微调方法论);
  • 原生函数调用(Native Function Calling):与 Mistral Large 一样经过函数调用训练,这使它成为最早支持函数调用的开源模型之一。

对照实验:NeMo(Tekken)与 Large 的分词效率对比

原文档用一段包含函数定义的消息(查询巴黎天气并附带 get_current_weather 工具)来对比两个模型的分词数量。先安装 Mistral 的官方分词工具包:

pip install mistral-common

Notebook 输出显示 mistral-common 1.4.4 安装成功,并会连带安装 sentencepiece 0.2.0tiktoken 0.7.0regex 等依赖(numpypydanticjsonschema 等作为既有依赖保留)。

第一段代码使用 NeMo 对应模型名 open-mistral-nemo

# Import needed packages:
from mistral_common.protocol.instruct.messages import (
    UserMessage,
)
from mistral_common.protocol.instruct.request import ChatCompletionRequest
from mistral_common.protocol.instruct.tool_calls import (
    Function,
    Tool,
)
from mistral_common.tokens.tokenizers.mistral import MistralTokenizer

# Load Mistral tokenizer

model_name = "open-mistral-nemo"

tokenizer = MistralTokenizer.from_model(model_name)

# Tokenize a list of messages
tokenized = tokenizer.encode_chat_completion(
    ChatCompletionRequest(
        tools=[
            Tool(
                function=Function(
                    name="get_current_weather",
                    description="Get the current weather",
                    parameters={
                        "type": "object",
                        "properties": {
                            "location": {
                                "type": "string",
                                "description": "The city and state, e.g. San Francisco, CA",
                            },
                            "format": {
                                "type": "string",
                                "enum": ["celsius", "fahrenheit"],
                                "description": "The temperature unit to use. Infer this from the user's location.",
                            },
                        },
                        "required": ["location", "format"],
                    },
                )
            )
        ],
        messages=[
            UserMessage(content="What's the weather like today in Paris"),
        ],
        model=model_name,
    )
)
tokens, text = tokenized.tokens, tokenized.text

# Count the number of tokens
print(len(tokens))

第二段代码使用 Mistral Large 对应模型名 mistral-large-latest,请求结构完全相同:

# Import needed packages:
from mistral_common.protocol.instruct.messages import (
    UserMessage,
)
from mistral_common.protocol.instruct.request import ChatCompletionRequest
from mistral_common.protocol.instruct.tool_calls import (
    Function,
    Tool,
)
from mistral_common.tokens.tokenizers.mistral import MistralTokenizer

# Load Mistral tokenizer

model_name = "mistral-large-latest"

tokenizer = MistralTokenizer.from_model(model_name)

# Tokenize a list of messages
tokenized = tokenizer.encode_chat_completion(
    ChatCompletionRequest(
        tools=[
            Tool(
                function=Function(
                    name="get_current_weather",
                    description="Get the current weather",
                    parameters={
                        "type": "object",
                        "properties": {
                            "location": {
                                "type": "string",
                                "description": "The city and state, e.g. San Francisco, CA",
                            },
                            "format": {
                                "type": "string",
                                "enum": ["celsius", "fahrenheit"],
                                "description": "The temperature unit to use. Infer this from the user's location.",
                            },
                        },
                        "required": ["location", "format"],
                    },
                )
            )
        ],
        messages=[
            UserMessage(content="What's the weather like today in Paris"),
        ],
        model=model_name,
    )
)
tokens, text = tokenized.tokens, tokenized.text

# Count the number of tokens
print(len(tokens))

这段对比中包含了两个值得展开的技术点:

  1. 函数定义的 JSON Schema 如何影响 token 数:两段代码都把 get_current_weather 的完整 JSON Schema(属性、枚举、必填项)编码进消息流。函数 schema 是函数调用场景下"隐形 token 消耗"的主要来源,schema 写得越冗长,每轮请求的基础 token 开销就越大;
  2. Tekken 的效率直观可见:在仓库 Notebook 的真实输出中,同一请求在 open-mistral-nemo 上分词得到 128 个 token,而在 mistral-large-latest 上得到 135 个 token。NeMo 用更少 token 表达同等内容,正是课程所说"更高效分词"的可量化证据——在长对话与高频调用场景中,这种差距会累积成显著的成本差异。

三款模型如何选:一张决策清单

把原文档三节内容汇总成可落地的选型逻辑:

  • 做企业级 RAG、复杂函数调用、多语言/代码生成 → 选 Mistral Large 2:128k 上下文窗口能容纳更多检索证据,数学与代码任务准确率更高;
  • 做高频、对成本与延迟敏感的任务(摘要、情感分析、翻译、代码审查)→ 选 Mistral Small:便宜约 80%、响应快、部署门槛低;
  • 需要开源合规、可自托管或深度微调 → 选 Mistral NeMo:Apache-2.0、Tekken 分词更省 token、支持原生函数调用与微调。

在课程中继续深入的方向

Mistral 只是课程中众多模型家族之一(可对比第 21 课 Meta 模型专题 21-meta/README.md)。若要进一步消化本课涉及的能力点,建议按主题回到课程对应章节:

想直接动手运行,推荐把 20-mistral/python/githubmodels-assignment.ipynb 导入到本地 Jupyter 或 Visual Studio Code Notebook 环境中,配置好推理凭据后从上到下逐格执行——RAG 示例与分词对比两节均已预置了完整输出,可作为你运行结果的对照基准。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388