简介

本文将从源码角度解读Qwen3-VL模型视频作为输入的预处理逻辑。这里所指的源码是transformers仓库中Qwen3-VL模型inference阶段所涉及的代码。

1.准备工作

视频信息

  • 总帧数: 153 帧
  • FPS: 30.0
  • 分辨率: 768 × 1152 (宽 × 高)

inference代码

Qwen3-VL中视频作为输入时候的inference代码:

from transformers import AutoModelForImageTextToText, AutoProcessormodel_dir = "Qwen/Qwen3-VL-2B-Instruct"# 不同尺寸模型的配置信息有所不同,需要甄别预处理部分的配置是否不同messages = [    {"role": "system", "content": [{"type": "text", "text": "You are a helpful assistant."}]},    {        "role": "user",        "content": [            {                "type": "video",                "video": "data/Standard_Mode_Starting_from_her_iconic_over_th.mp4"            },            {"type": "text", "text": "描述下这个视频"},        ],    }]processor = AutoProcessor.from_pretrained(model_dir)# Preparation for inferenceinputs = processor.apply_chat_template(    messages,    tokenize=True,    add_generation_prompt=True,    return_dict=True,    return_tensors="pt")print("inputs keys=", list(inputs.keys()))# inputs keys= ['input_ids', 'attention_mask', 'pixel_values_videos', 'video_grid_thw']print("inputs['input_ids'] shape= ", inputs['input_ids'].shape)print("inputs['pixel_values_videos'] shape= ", inputs['pixel_values_videos'].shape)print("inputs['video_grid_thw']= ", inputs['video_grid_thw'])

测试代码运行结果:

inputs keys= ['input_ids', 'attention_mask', 'pixel_values_videos', 'video_grid_thw']inputs['input_ids'] shape=  torch.Size([1, 4383])inputs['pixel_values_videos'] shape=  torch.Size([17280, 1536])inputs['video_grid_thw']=  tensor([[ 5, 72, 48]])

以下将从源码角度推导出:

inputs['input_ids'] shape=  torch.Size([1, 4383])inputs['pixel_values_videos'] shape=  torch.Size([17280, 1536])inputs['video_grid_thw']=  tensor([[ 5, 72, 48]])

2.处理流程概述

Qwen3-VL 的视频处理流程可以分为以下几个主要阶段:

  • Chat Template 应用阶段
  • 将用户消息转换为带有特殊标记的文本序列
  • 插入视频占位符 <|vision_start|><|video_pad|><|vision_end|>
  • 视频采样阶段
  • 根据 FPS 参数从原始视频中均匀采样帧
  • 默认采样 2 FPS,受 min_frames=4max_frames=768 约束
  • 视频预处理阶段
  • 智能调整视频尺寸(smart_resize)
  • 归一化和重塑为 patch 格式
  • 文本替换阶段
  • 将视频占位符替换为带时间戳的帧序列
  • 每帧包含时间戳和多个 <|video_pad|> token
  • Tokenization 阶段
  • 将最终文本序列转换为 token IDs

  1. 详细计算过程
    =========

阶段 1: Chat Template 生成初始文本

根据 tokenizer_config.json 中的 chat template,输入消息会被转换为:

<|im_start|>systemYou are a helpful assistant.<|im_end|><|im_start|>user<|vision_start|><|video_pad|><|vision_end|>描述下这个视频<|im_end|><|im_start|>assistant

Token 数量计算(不含视频):

  • <|im_start|>: 1 token (ID: 151644)
  • system\n: 2 tokens
  • You are a helpful assistant.: 6 tokens
  • <|im_end|>\n: 2 tokens
  • <|im_start|>: 1 token
  • user\n: 2 tokens
  • <|vision_start|>: 1 token (ID: 151652)
  • <|video_pad|>: 1 token (ID: 151656) - 将被替换
  • <|vision_end|>: 1 token (ID: 151653)
  • 描述下这个视频: 4 tokens (中文字符)
  • <|im_end|>\n: 2 tokens
  • <|im_start|>: 1 token
  • assistant\n: 2 tokens

基础 token 数(不含视频内容): 1 + 2 + 6 + 2 + 1 + 2 + 1 + 1 + 1 + 4 + 2 + 1 + 2 = 26 tokens


视频预处理概览

整体的视频预处理入口在src/transformers/models/qwen3_vl/processing_qwen3_vl.pyQwen3VLProcessor类的 __call__函数:

videos_inputs = self.video_processor(videos=videos, **output_kwargs["videos_kwargs"])返回结果 videos_inputs 里面有['pixel_values_videos', 'video_grid_thw', 'video_metadata']videos_inputs["pixel_values_videos"].shape 为 torch.Size([17280, 1536])videos_inputs["video_grid_thw"] 值为 tensor([[ 5, 72, 48]])videos_inputs["video_metadata"] 值为(VideoMetadata(total_num_frames=153, fps=30.0, width=768, height=1152, duration=5.1, video_backend='torchvision', frames_indices=array([  0,  17,  34,  51,  68,  84, 101, 118, 135, 152])),)

PS:顺便打印一下此时的 text 信息:

<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n<|im_start|>user\n<|vision_start|><|video_pad|><|vision_end|>描述下这个视频<|im_end|>\n<|im_start|>assistant\n

需要注意:此时上述的self.video_processor类型是

'transformers.models.qwen3_vl.video_processing_qwen3_vl.Qwen3VLVideoProcessor'

需要注意,BaseVideoProcessor类中__call__定义如下:

def __call__(self, videos, **kwargs) -> BatchFeature:        return self.preprocess(videos, **kwargs)

而从Qwen3VLVideoProcessor类的定义:class Qwen3VLVideoProcessor(BaseVideoProcessor)可以看出继承了BaseVideoProcessor,因此videos_inputs = self.video_processor(videos=videos, **output_kwargs["videos_kwargs"])这行代码实际上是运行了:BaseVideoProcessor中的preprocess函数。因为,Qwen3VLVideoProcessor类中并未重写preprocess函数,但是重写了_preprocess函数。

因此,整体的预处理逻辑的框架是来自于BaseVideoProcessor中定义的preprocess函数,但是其中的_preprocess函数使用Qwen3-VL中src/transformers/models/qwen3_vl/video_processing_qwen3_vl.py定义的_preprocess函数。

因此,Qwen3VLVideoProcessor中的预处理逻辑是:src/transformers/video_processing_utils.py中的preprocess函数,并将其中的_preprocess改用src/transformers/models/qwen3_vl/video_processing_qwen3_vl.py定义的_preprocess函数。

src/transformers/video_processing_utils.pyBaseVideoProcessorpreprocess定义如下:

def preprocess(        self,        videos: VideoInput,        **kwargs: Unpack[VideosKwargs],    ) -> BatchFeature:        validate_kwargs(            captured_kwargs=kwargs.keys(),            valid_processor_keys=list(self.valid_kwargs.__annotations__.keys()) + ["return_tensors"],        )        # Perform type validation on received kwargs        validate_typed_dict(self.valid_kwargs, kwargs)        # Set default kwargs from self. This ensures that if a kwarg is not provided        # by the user, it gets its default value from the instance, or is set to None.        for kwarg_name in self.valid_kwargs.__annotations__:            kwargs.setdefault(kwarg_name, getattr(self, kwarg_name, None))        input_data_format = kwargs.pop("input_data_format")        do_sample_frames = kwargs.pop("do_sample_frames")        device = kwargs.pop("device")        video_metadata = kwargs.pop("video_metadata")        sample_indices_fn = partial(self.sample_frames, **kwargs) if do_sample_frames else None        videos, video_metadata = self._decode_and_sample_videos(            videos,            video_metadata=video_metadata,            do_sample_frames=do_sample_frames,            sample_indices_fn=sample_indices_fn,        )        videos = self._prepare_input_videos(videos=videos, input_data_format=input_data_format, device=device)        kwargs = self._further_process_kwargs(**kwargs)        self._validate_preprocess_kwargs(**kwargs)        # Pop kwargs that are not needed in _preprocess        kwargs.pop("data_format")        return_metadata = kwargs.pop("return_metadata")        preprocessed_videos = self._preprocess(videos=videos, **kwargs)        if return_metadata:            preprocessed_videos["video_metadata"] = video_metadata        return preprocessed_videos

只需要理清楚上面这个预处理逻辑即可。核心是:

  • _decode_and_sample_videos
  • _prepare_input_videos
  • _preprocess

阶段 2: 视频帧采样

_decode_and_sample_videos这个函数是视频处理的核心入口,负责:

  1. 标准化输入格式:将各种格式的视频输入转换为统一的批处理格式
  2. 执行帧采样:根据自定义的采样函数对视频帧进行采样
  3. 保存采样信息:将采样的帧索引保存到元数据中,供后续使用

以下主要介绍帧采样的逻辑。

采样调用逻辑

视频帧采样 sample_frames 是在 BaseVideoProcessor.preprocess() 方法中被调用的。具体代码src/transformers/video_processing_utils.py具体流程如下:

调用链路:

1、用户调用: video_processor(videos=videos, **kwargs) 2、__call__方法 (在 video_processing_utils.py):

def __call__(self, videos, **kwargs) -> BatchFeature:    return self.preprocess(videos, **kwargs)

3、preprocess 方法 (在 video_processing_utils.py):

def preprocess(self, videos: VideoInput, **kwargs) -> BatchFeature:    # ... 参数处理 ...        # 关键代码:创建采样函数    sample_indices_fn = partial(self.sample_frames, **kwargs) if do_sample_frames else None        # 调用 _decode_and_sample_videos,在这里执行采样    videos, video_metadata = self._decode_and_sample_videos(        videos,        video_metadata=video_metadata,        do_sample_frames=do_sample_frames,        sample_indices_fn=sample_indices_fn,  # 传入采样函数    )    # ... 后续处理 ...
4、`_decode_and_sample_videos` 方法 (在video\_processing\_utils.py):
def _decode_and_sample_videos(self, videos, video_metadata, do_sample_frames, sample_indices_fn):    # ...     if is_valid_video(videos[0]) and do_sample_frames:        sampled_videos = []        sampled_metadata = []        for video, metadata in zip(videos, video_metadata):            # 这里调用 sample_indices_fn,实际上就是 self.sample_frames            indices = sample_indices_fn(metadata=metadata)            metadata.frames_indices = indices            sampled_videos.append(video[indices])  # 根据索引采样帧            sampled_metadata.append(metadata)

5、sample_frames方法 (在 video_processing_qwen3_vl.py:):

  • Qwen3VL 重写了这个方法,实现自定义的采样逻辑
  • 根据 fps=2 和视频元数据计算需要采样的帧数
  • 使用 np.linspace 均匀采样

关键点:

  • do_sample_frames=True 是默认值(在 Qwen3VLVideoProcessor 中定义)
  • 采样发生在视频预处理 _preprocess 之前
  • 采样后的帧索引会保存在 metadata.frames_indices 中,供后续的时间戳计算使用

源码(src/transformers/video_processing_utils.py)中的调用路径如下:

processor.__call__()   → video_processor.__call__()    → video_processor.preprocess()      → video_processor._decode_and_sample_videos()        → video_processor.sample_frames()  ← 这里执行采样!      → video_processor._preprocess()  ← 这里处理采样后的帧

视频采样逻辑

采样参数:

  • fps = 2 (默认值,从 Qwen3VLVideoProcessor 类)
  • min_frames = 4
  • max_frames = 768
  • temporal_patch_size = 2

采样计算:

# 源码位置: src/transformers/models/qwen3_vl/video_processing_qwen3_vl.py - sample_frames()total_num_frames = 153# 视频总帧数video_fps = 30.0        # 视频原始 FPS# 根据目标 FPS 计算需要采样的帧数num_frames = int(total_num_frames / video_fps * fps)num_frames = int(153 / 30.0 * 2) = int(10.2) = 10# 应用约束num_frames = min(max(num_frames, min_frames), max_frames, total_num_frames)num_frames = min(max(10, 4), 768, 153) = 10# 均匀采样索引indices = np.linspace(0, 153-1, 10).round().astype(int)# indices = [0, 17, 34, 51, 68, 85, 102, 119, 136, 152]

这个值跟src/transformers/models/qwen3_vl/processing_qwen3_vl.py中运行到:

videos_inputs = self.video_processor(videos=videos, **output_kwargs["videos_kwargs"])

打印出的 videos_inputs[“video_metadata”] 值一样:

frames_indices=array([  0,  17,  34,  51,  68,  84, 101, 118, 135, 152])),)

采样结果: 从 153 帧中采样 10 帧


阶段 3: 视频预处理与 Smart Resize

_prepare_input_videos这个函数是视频预处理的格式标准化阶段,负责:

  1. 类型转换:将 NumPy 数组转换为 PyTorch 张量
  2. 通道维度标准化:统一为 channels_first 格式
  3. 设备迁移:将张量移动到指定设备(CPU/GPU)

这是在采样之后、实际图像处理(resize、normalize 等)之前的关键步骤。

以下直接介绍核心预处理_preprocess中的smart_resize的细节,smart_resize的入参:

smart_resize(                    num_frames=num_frames,                    height=height,                    width=width,                    temporal_factor=temporal_patch_size,                    factor=patch_size * merge_size,                    min_pixels=size.shortest_edge,                    max_pixels=size.longest_edge,                )

输入参数:

  • 原始尺寸: 768 × 1152 (W × H)
  • 采样帧数(num_frames): 10
  • temporal_patch_size = 2
  • patch_size = 16
  • merge_size = 2
  • min_pixels = size.shortest_edge = 4096
  • max_pixels = size.longest_edge = 25165824

min、max 像素值是来自配置文件:

"size": {        "longest_edge": 25165824,        "shortest_edge": 4096    },

Smart Resize 计算

# 源码位置: video_processing_qwen3_vl.py - smart_resize()num_frames = 10height = 1152width = 768factor = patch_size * merge_size = 16 * 2 = 32temporal_factor = 2# 步骤 1: 初步调整到 factor (32) 的倍数h_bar = round(height / factor) * factorw_bar = round(width / factor) * factort_bar = math.ceil(num_frames / temporal_factor) * temporal_factor# 代入具体值:h_bar = round(1152 / 32) * 32 = 36 * 32 = 1152w_bar = round(768 / 32) * 32 = 24 * 32 = 768t_bar = ceil(10 / 2) * 2 = 5 * 2 = 10# 步骤 2: 检查是否超过 max_pixelstotal_pixels = 10 * 1152 * 768 = 8,847,360max_pixels = 25,165,8248,847,360 < 25,165,824 ✓  # 不超过,不需要缩小# 步骤 3: 检查是否低于 min_pixelstotal_pixels = 8,847,360min_pixels = 4,0968,847,360 > 4,096 ✓  # 不低于,不需要放大

由于:

  • 原始尺寸已经是 32 的倍数
  • 总像素数在合理范围内 [4,096, 25,165,824]
  • 配置参数设置非常宽松

因此尺寸保持不变:h_bar = 1152, w_bar = 768

帧数 Padding

# 源码位置: video_processing_qwen3_vl.py - _preprocess()T = 10  # 采样的帧数temporal_patch_size = 2# 检查是否需要 paddingpad = -T % temporal_patch_size = -10 % 2 = 0# 不需要 padding,10 已经是 2 的倍数

Padding 后帧数: 10 帧

Grid 计算

grid_t = 10 // temporal_patch_size = 10 // 2 = 5grid_h = 1152 // patch_size = 1152 // 16 = 72grid_w = 768 // patch_size = 768 // 16 = 48

Grid 尺寸: [5, 72, 48] ✓ 与最开始的测试脚本得到的结果一致。

Patch 重组与展平

# 源码位置: video_processing_qwen3_vl.py - _preprocess()# patches shape: [batch, T, C, H, W] = [1, 10, 3, 1152, 768]# 重组为 patch 格式patches = patches.reshape(    batch_size,                    # 1    grid_t,                        # 5    temporal_patch_size,           # 2    channel,                       # 3    grid_h // merge_size,          # 72 // 2 = 36    merge_size,                    # 2    patch_size,                    # 16    grid_w // merge_size,          # 48 // 2 = 24    merge_size,                    # 2    patch_size,                    # 16)# Shape: [1, 5, 2, 3, 36, 2, 16, 24, 2, 16]# 转置patches = patches.permute(0, 1, 4, 7, 5, 8, 3, 2, 6, 9)# Shape: [1, 5, 36, 24, 2, 2, 3, 2, 16, 16]# 展平flatten_patches = patches.reshape(    batch_size,                                              # 1    grid_t * grid_h * grid_w,                               # 5 * 72 * 48 = 17,280    channel * temporal_patch_size * patch_size * patch_size # 3 * 2 * 16 * 16 = 1,536)# Shape: [1, 17280, 1536]# 最终输出(去掉 batch 维度)pixel_values_videos.shape = [17280, 1536]

pixel_values_videos 形状: [17280, 1536]

计算验证:

  • 总 patch 数: 5 × 72 × 48 = 17,280
  • 每个 patch 维度: 3 × 2 × 16 × 16 = 1,536

这个计算结果与inference脚本得到的结果一致。


阶段 4: 文本替换 - 视频占位符展开

时间戳计算

# 源码位置: processing_qwen3_vl.py - _calculate_timestamps()indices = [0, 17, 34, 51, 68, 85, 102, 119, 136, 152]fps = 30.0merge_size = 2# 步骤 1: 检查是否需要 padding# len(indices) = 10, 10 % 2 = 0, 不需要 padding# 步骤 2: 计算每帧的时间戳(秒)timestamps = [idx / fps for idx in indices]# timestamps = [0.0, 0.567, 1.133, 1.7, 2.267, 2.833, 3.4, 3.967, 4.533, 5.067]# 步骤 3: 合并相邻帧的时间戳(因为 merge_size=2)# 每 2 帧取平均merged_timestamps = [    (timestamps[i] + timestamps[i + merge_size - 1]) / 2    for i in range(0, len(timestamps), merge_size)]# i=0: (0.0 + 0.567) / 2 = 0.283# i=2: (1.133 + 1.7) / 2 = 1.417# i=4: (2.267 + 2.833) / 2 = 2.550# i=6: (3.4 + 3.967) / 2 = 3.683# i=8: (4.533 + 5.067) / 2 = 4.800# merged_timestamps = [0.283, 1.417, 2.550, 3.683, 4.800]# 实测脚本运行中`_calculate_timestamps`返回结果如下:# [0.2833333333333333, 1.4166666666666665, 2.533333333333333, 3.65, 4.783333333333333]因此真实情况的时间戳是:<0.3 seconds><1.4 seconds><2.5 seconds><3.6 seconds><4.8 seconds>以下推演,仍然按照估算的值进行。

时间戳列表: [0.3, 1.4, 2.6, 3.7, 4.8] (保留一位小数)

视频占位符替换

# 源码位置: processing_qwen3_vl.py - __call__()video_grid_thw = [5, 72, 48]merge_length = merge_size ** 2 = 2 ** 2 = 4# 每帧的 token 数量frame_seqlen = video_grid_thw[1:].prod() // merge_lengthframe_seqlen = (72 * 48) // 4 = 3456 // 4 = 864# 构建视频占位符video_placeholder = ""for frame_idx in range(5):  # grid_t = 5    curr_time = merged_timestamps[frame_idx]    video_placeholder += f"<{curr_time:.1f} seconds>"    video_placeholder += "<|vision_start|>" + "<|video_pad|>" * 864 + "<|vision_end|>"# 展开后的结构:# <0.3 seconds><|vision_start|><|video_pad|>×864<|vision_end|># <1.4 seconds><|vision_start|><|video_pad|>×864<|vision_end|># <2.6 seconds><|vision_start|><|video_pad|>×864<|vision_end|># <3.7 seconds><|vision_start|><|video_pad|>×864<|vision_end|># <4.8 seconds><|vision_start|><|video_pad|>×864<|vision_end|>

每帧的 token 组成:

  • 时间戳文本: <X.X seconds> ≈ 5-6 tokens
  • <|vision_start|>: 1 token
  • <|video_pad|> × 864: 864 tokens
  • <|vision_end|>: 1 token
  • 每帧总计: 约 871 tokens = 5+1+864+1=871

5 帧总计: 约 5 × 871 = 4355 tokens PS: 以上按照时间戳的文本表示占用5个token进行估算,但是这个是浮动的。 比如真实情况的时间戳如下:

<0.3 seconds><1.4 seconds><2.5 seconds><3.6 seconds><4.8 seconds>

实际占用的是30个token,并不是按照5x5=25的估算结果。因此最终计算结果应该再 +5 个token

最终的text结果:

'<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n<|im_start|>user\n<0.3 seconds><|vision_start|><|video_pad|>...<|video_pad|><|vision_end|>描述下这个视频<|im_end|>\n<|im_start|>assistant\n'

注意:这里<|vision_start|>之前有一个时间戳,比如第一帧<0.3 seconds><|vision_start|><|video_pad|>..<|vision_end|>

这个text的基础文本框架是:

'<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n<|im_start|>user\n描述下这个视频<|im_end|>\n<|im_start|>assistant\n'

这个基础文本框架的token数是23。


阶段 5: 最终 Token 计算

# 基础文本 tokens(不含视频): 23 tokens# 视频相关 tokens: 4355 tokens# 总计: 23 + 30 + 5*(2+864)=438323=3+6+2+3+4+5 (基础文本框架的token数)

这个结果与inference脚本的结果一致: 4383 tokens

分析过程需要特别注意: 时间戳文本的精确 tokenization。

比如:

test_str = "<0.3 seconds><|video_pad|><1.4 seconds><|video_pad|><2.5 seconds><|video_pad|><3.6 seconds><|video_pad|><4.8 seconds><|video_pad|>"test_str_tokens = processor.tokenizer(test_str)print("test str token num=", len(test_str_tokens['input_ids']))

此时的结果是35,然后再减掉5个<|video_pad|>,所以这个时间戳占用的token数是30个。

如果:

test_str = "<0.3 seconds><1.4 seconds><2.5 seconds><3.6 seconds><4.8 seconds>"test_str_tokens = processor.tokenizer(test_str)print("test str token num=", len(test_str_tokens['input_ids']))

打印结果是23。


4.关键参数总结

参数 说明
patch_size 16 空间 patch 大小
temporal_patch_size 2 时间 patch 大小
merge_size 2 合并大小
fps 2 采样帧率
min_frames 4 最小帧数
max_frames 768 最大帧数
min_pixels 131,072 最小像素数
max_pixels 786,432 最大像素数

普通人如何抓住AI大模型的风口?

为什么要学AI大模型

当下,⼈⼯智能市场迎来了爆发期,并逐渐进⼊以⼈⼯通⽤智能(AGI)为主导的新时代。企业纷纷官宣“ AI+ ”战略,为新兴技术⼈才创造丰富的就业机会,⼈才缺⼝将达 400 万!

DeepSeek问世以来,生成式AI和大模型技术爆发式增长,让很多岗位重新成了炙手可热的新星,岗位薪资远超很多后端岗位,在程序员中稳居前列。

在这里插入图片描述

与此同时AI与各行各业深度融合,飞速发展,成为炙手可热的新风口,企业非常需要了解AI、懂AI、会用AI的员工,纷纷开出高薪招聘AI大模型相关岗位。
在这里插入图片描述

AI大模型开发工程师对AI大模型需要了解到什么程度呢?我们先看一下招聘需求:

在这里插入图片描述

知道人家要什么能力,一切就好办了!我整理了AI大模型开发工程师需要掌握的知识如下:

大模型基础知识

你得知道市面上的大模型产品生态和产品线;还要了解Llama、Qwen等开源大模型与OpenAI等闭源模型的能力差异;以及了解开源模型的二次开发优势,以及闭源模型的商业化限制,等等。

img

了解这些技术的目的在于建立与算法工程师的共通语言,确保能够沟通项目需求,同时具备管理AI项目进展、合理分配项目资源、把握和控制项目成本的能力。

产品经理还需要有业务sense,这其实就又回到了产品人的看家本领上。我们知道先阶段AI的局限性还非常大,模型生成的内容不理想甚至错误的情况屡见不鲜。因此AI产品经理看技术,更多的是从技术边界、成本等角度出发,选择合适的技术方案来实现需求,甚至用业务来补足技术的短板。

AI Agent

现阶段,AI Agent的发展可谓是百花齐放,甚至有人说,Agent就是未来应用该有的样子,所以这个LLM的重要分支,必须要掌握。

Agent,中文名为“智能体”,由控制端(Brain)、感知端(Perception)和行动端(Action)组成,是一种能够在特定环境中自主行动、感知环境、做出决策并与其他Agent或人类进行交互的计算机程序或实体。简单来说就是给大模型这个大脑装上“记忆”、装上“手”和“脚”,让它自动完成工作。

Agent的核心特性

自主性: 能够独立做出决策,不依赖人类的直接控制。

适应性: 能够根据环境的变化调整其行为。

交互性: 能够与人类或其他系统进行有效沟通和交互。

img

对于大模型开发工程师来说,学习Agent更多的是理解它的设计理念和工作方式。零代码的大模型应用开发平台也有很多,比如dify、coze,拿来做一个小项目,你就会发现,其实并不难。

AI 应用项目开发流程

如果产品形态和开发模式都和过去不一样了,那还画啥原型?怎么排项目周期?这将深刻影响产品经理这个岗位本身的价值构成,所以每个AI产品经理都必须要了解它。

img

看着都是新词,其实接触起来,也不难。

从0到1的大模型系统学习籽料

最近很多程序员朋友都已经学习或者准备学习 AI 大模型,后台也经常会有小伙伴咨询学习路线和学习资料,我特别拜托北京清华大学学士和美国加州理工学院博士学位的鲁为民老师(吴文俊奖得主)
在这里插入图片描述

给大家准备了一份涵盖了AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频 全系列的学习资料,这些学习资料不仅深入浅出,而且非常实用,让大家系统而高效地掌握AI大模型的各个知识点。

图片

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

适学人群

应届毕业生‌: 无工作经验但想要系统学习AI大模型技术,期待通过实战项目掌握核心技术。

零基础转型‌: 非技术背景但关注AI应用场景,计划通过低代码工具实现“AI+行业”跨界‌。

业务赋能突破瓶颈: 传统开发者(Java/前端等)学习Transformer架构与LangChain框架,向AI全栈工程师转型‌。
在这里插入图片描述

AI大模型系统学习路线

在面对AI大模型开发领域的复杂与深入,精准学习显得尤为重要。一份系统的技术路线图,不仅能够帮助开发者清晰地了解从入门到精通所需掌握的知识点,还能提供一条高效、有序的学习路径。

  • 基础篇,包括了大模型的基本情况,核心原理,带你认识了解大模型提示词,Transformer架构,预训练、SFT、RLHF等一些基础概念,用最易懂的方式带你入门AI大模型
  • 进阶篇,你将掌握RAG,Langchain、Agent的核心原理和应用,学习如何微调大模型,让大模型更适合自己的行业需求,私有化部署大模型,让自己的数据更加安全
  • 项目实战篇,会手把手一步步带着大家练习企业级落地项目,比如电商行业的智能客服、智能销售项目,教育行业的智慧校园、智能辅导项目等等

img

但知道是一回事,做又是另一回事,初学者最常遇到的问题主要是理论知识缺乏、资源和工具的限制、模型理解和调试的复杂性,在这基础上,找到高质量的学习资源,不浪费时间、不走弯路,又是重中之重。

AI大模型入门到实战的视频教程+项目包

看视频学习是一种高效、直观、灵活且富有吸引力的学习方式,可以更直观地展示过程,能有效提升学习兴趣和理解力,是现在获取知识的重要途径

在这里插入图片描述
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
在这里插入图片描述

海量AI大模型必读的经典书籍(PDF)

阅读AI大模型经典书籍可以帮助读者提高技术水平,开拓视野,掌握核心技术,提高解决问题的能力,同时也可以借鉴他人的经验。对于想要深入学习AI大模型开发的读者来说,阅读经典书籍是非常有必要的。
在这里插入图片描述

600+AI大模型报告(实时更新)

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。
在这里插入图片描述

AI大模型面试真题+答案解析

我们学习AI大模型必然是想找到高薪的工作,下面这些面试题都是总结当前最新、最热、最高频的面试题,并且每道题都有详细的答案,面试前刷完这套面试题资料,小小offer,不在话下
在这里插入图片描述

在这里插入图片描述

AI时代,企业最需要的是既懂技术、又有实战经验的复合型人才,**当前人工智能岗位需求多,薪资高,前景好。**在职场里,选对赛道就能赢在起跑线。抓住AI这个风口,相信下一个人生赢家就是你!机会,永远留给有准备的人。

如何获取?

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐