news 2026/3/7 4:47:42

SmallThinker-3B-Preview惊艳效果:生成可执行Python代码并附带单元测试用例

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SmallThinker-3B-Preview惊艳效果:生成可执行Python代码并附带单元测试用例

SmallThinker-3B-Preview惊艳效果:生成可执行Python代码并附带单元测试用例

最近在探索各种轻量级大模型时,我发现了一个特别有意思的模型——SmallThinker-3B-Preview。这个模型最让我惊讶的地方是,它不仅能够生成Python代码,还能自动为这些代码生成完整的单元测试用例。对于一个经常需要写代码又懒得写测试的程序员来说,这简直是天降福音。

SmallThinker-3B-Preview是在Qwen2.5-3b-Instruct模型基础上微调而来的。它的设计目标很明确:一是为了在资源有限的边缘设备上部署,二是作为更大模型QwQ-32B-Preview的草稿模型,据说速度能提升70%。但对我来说,最吸引人的是它在代码生成和测试用例生成方面的表现。

1. 核心能力概览

SmallThinker-3B-Preview虽然只有3B参数,但在代码生成任务上展现出了超出预期的能力。我花了一周时间测试了各种场景,发现它有几个特别突出的特点。

1.1 代码生成质量

这个模型生成的Python代码质量相当不错。我测试了从简单的排序算法到复杂的数据处理函数,它都能生成结构清晰、符合PEP8规范的代码。更难得的是,它生成的代码通常都带有合理的注释,这让代码的可读性大大提升。

比如我让它生成一个快速排序函数,它给出的代码是这样的:

def quick_sort(arr): """ 快速排序算法实现 参数: arr (list): 需要排序的列表 返回: list: 排序后的列表 """ if len(arr) <= 1: return arr pivot = arr[len(arr) // 2] left = [x for x in arr if x < pivot] middle = [x for x in arr if x == pivot] right = [x for x in arr if x > pivot] return quick_sort(left) + middle + quick_sort(right)

代码结构清晰,注释完整,完全可以直接使用。

1.2 单元测试自动生成

这才是SmallThinker真正让我惊艳的地方。每次生成代码后,它都会自动生成对应的单元测试用例。这些测试用例覆盖了正常情况、边界情况和异常情况,测试质量相当专业。

继续上面的快速排序例子,它生成的测试用例是这样的:

import unittest class TestQuickSort(unittest.TestCase): """快速排序算法的单元测试""" def test_empty_list(self): """测试空列表""" self.assertEqual(quick_sort([]), []) def test_single_element(self): """测试单个元素列表""" self.assertEqual(quick_sort([5]), [5]) def test_sorted_list(self): """测试已排序列表""" self.assertEqual(quick_sort([1, 2, 3, 4, 5]), [1, 2, 3, 4, 5]) def test_reverse_sorted(self): """测试逆序列表""" self.assertEqual(quick_sort([5, 4, 3, 2, 1]), [1, 2, 3, 4, 5]) def test_duplicate_elements(self): """测试包含重复元素的列表""" self.assertEqual(quick_sort([3, 1, 4, 1, 5, 9, 2, 6, 5]), [1, 1, 2, 3, 4, 5, 5, 6, 9]) def test_negative_numbers(self): """测试包含负数的列表""" self.assertEqual(quick_sort([-5, -1, -3, 0, 2]), [-5, -3, -1, 0, 2]) def test_mixed_types_error(self): """测试混合类型列表应该抛出异常""" with self.assertRaises(TypeError): quick_sort([1, 'a', 3]) if __name__ == '__main__': unittest.main()

看到这样的测试用例,我简直不敢相信这是一个3B模型生成的。测试用例覆盖了各种边界情况,甚至考虑了类型错误的情况。

2. 实际效果展示

为了更全面地展示SmallThinker的能力,我测试了几个不同难度的场景。

2.1 数据处理函数生成

我让模型生成一个从CSV文件中读取数据并计算统计信息的函数。它生成的代码和测试用例都很完整。

生成的函数代码:

import csv from typing import List, Dict, Union def calculate_csv_statistics(file_path: str) -> Dict[str, Union[float, int]]: """ 计算CSV文件的统计信息 参数: file_path (str): CSV文件路径 返回: dict: 包含统计信息的字典 """ statistics = { 'row_count': 0, 'column_count': 0, 'numeric_columns': {} } try: with open(file_path, 'r', encoding='utf-8') as file: reader = csv.reader(file) rows = list(reader) if not rows: return statistics statistics['row_count'] = len(rows) - 1 # 减去标题行 statistics['column_count'] = len(rows[0]) # 尝试识别数值列并计算统计信息 for col_idx in range(statistics['column_count']): numeric_values = [] for row_idx in range(1, len(rows)): if row_idx < len(rows) and col_idx < len(rows[row_idx]): try: value = float(rows[row_idx][col_idx]) numeric_values.append(value) except (ValueError, IndexError): continue if numeric_values: statistics['numeric_columns'][f'col_{col_idx}'] = { 'count': len(numeric_values), 'mean': sum(numeric_values) / len(numeric_values), 'min': min(numeric_values), 'max': max(numeric_values) } except FileNotFoundError: raise FileNotFoundError(f"文件 {file_path} 不存在") except Exception as e: raise RuntimeError(f"处理文件时出错: {str(e)}") return statistics

自动生成的测试用例:

import unittest import tempfile import os class TestCalculateCSVStatistics(unittest.TestCase): """CSV统计计算函数的单元测试""" def setUp(self): """测试前的准备工作""" self.temp_dir = tempfile.mkdtemp() def tearDown(self): """测试后的清理工作""" import shutil shutil.rmtree(self.temp_dir) def test_empty_csv(self): """测试空CSV文件""" temp_file = os.path.join(self.temp_dir, 'empty.csv') with open(temp_file, 'w', newline='', encoding='utf-8') as f: f.write('') result = calculate_csv_statistics(temp_file) self.assertEqual(result['row_count'], 0) self.assertEqual(result['column_count'], 0) self.assertEqual(result['numeric_columns'], {}) def test_csv_with_headers_only(self): """测试只有标题行的CSV""" temp_file = os.path.join(self.temp_dir, 'headers.csv') with open(temp_file, 'w', newline='', encoding='utf-8') as f: f.write('name,age,salary\n') result = calculate_csv_statistics(temp_file) self.assertEqual(result['row_count'], 0) self.assertEqual(result['column_count'], 3) self.assertEqual(result['numeric_columns'], {}) def test_csv_with_numeric_data(self): """测试包含数值数据的CSV""" temp_file = os.path.join(self.temp_dir, 'data.csv') with open(temp_file, 'w', newline='', encoding='utf-8') as f: f.write('name,age,salary\n') f.write('Alice,30,50000\n') f.write('Bob,25,45000\n') f.write('Charlie,35,55000\n') result = calculate_csv_statistics(temp_file) self.assertEqual(result['row_count'], 3) self.assertEqual(result['column_count'], 3) # 检查数值列的统计信息 self.assertIn('col_1', result['numeric_columns']) # age列 self.assertIn('col_2', result['numeric_columns']) # salary列 age_stats = result['numeric_columns']['col_1'] self.assertEqual(age_stats['count'], 3) self.assertAlmostEqual(age_stats['mean'], 30.0) self.assertEqual(age_stats['min'], 25) self.assertEqual(age_stats['max'], 35) def test_file_not_found(self): """测试文件不存在的情况""" with self.assertRaises(FileNotFoundError): calculate_csv_statistics('non_existent_file.csv') def test_malformed_csv(self): """测试格式错误的CSV""" temp_file = os.path.join(self.temp_dir, 'malformed.csv') with open(temp_file, 'w', newline='', encoding='utf-8') as f: f.write('col1,col2\n') f.write('value1\n') # 缺少一列 # 应该能正常处理,只是统计信息可能不完整 result = calculate_csv_statistics(temp_file) self.assertEqual(result['row_count'], 1) self.assertEqual(result['column_count'], 2) if __name__ == '__main__': unittest.main()

2.2 复杂算法实现

我尝试了一个更有挑战性的任务:生成一个简单的机器学习算法——K近邻分类器。结果让我很惊喜。

生成的KNN分类器代码:

import numpy as np from collections import Counter from typing import List, Tuple class KNNClassifier: """ K近邻分类器实现 参数: k (int): 邻居数量,默认为3 """ def __init__(self, k: int = 3): self.k = k self.X_train = None self.y_train = None def fit(self, X: np.ndarray, y: np.ndarray) -> None: """ 训练模型 参数: X (np.ndarray): 训练特征,形状为 (n_samples, n_features) y (np.ndarray): 训练标签,形状为 (n_samples,) """ self.X_train = X self.y_train = y def predict(self, X: np.ndarray) -> np.ndarray: """ 预测新样本的标签 参数: X (np.ndarray): 待预测样本,形状为 (n_samples, n_features) 返回: np.ndarray: 预测标签,形状为 (n_samples,) """ if self.X_train is None or self.y_train is None: raise ValueError("模型尚未训练,请先调用fit方法") predictions = [] for sample in X: # 计算与所有训练样本的距离 distances = np.sqrt(np.sum((self.X_train - sample) ** 2, axis=1)) # 获取最近的k个邻居的索引 k_indices = np.argsort(distances)[:self.k] # 获取这些邻居的标签 k_nearest_labels = self.y_train[k_indices] # 投票决定预测标签 most_common = Counter(k_nearest_labels).most_common(1) predictions.append(most_common[0][0]) return np.array(predictions) def score(self, X: np.ndarray, y: np.ndarray) -> float: """ 计算模型在测试集上的准确率 参数: X (np.ndarray): 测试特征 y (np.ndarray): 测试标签 返回: float: 准确率 """ predictions = self.predict(X) accuracy = np.mean(predictions == y) return accuracy

自动生成的测试用例同样专业:

import unittest import numpy as np class TestKNNClassifier(unittest.TestCase): """KNN分类器的单元测试""" def setUp(self): """测试前的准备工作""" self.knn = KNNClassifier(k=3) # 创建简单的训练数据 self.X_train = np.array([ [1, 2], [1.5, 1.8], [5, 8], [8, 8], [1, 0.6], [9, 11] ]) self.y_train = np.array([0, 0, 1, 1, 0, 1]) def test_initialization(self): """测试初始化""" knn = KNNClassifier(k=5) self.assertEqual(knn.k, 5) self.assertIsNone(knn.X_train) self.assertIsNone(knn.y_train) def test_fit_method(self): """测试fit方法""" self.knn.fit(self.X_train, self.y_train) np.testing.assert_array_equal(self.knn.X_train, self.X_train) np.testing.assert_array_equal(self.knn.y_train, self.y_train) def test_predict_without_fit(self): """测试未训练时预测应该报错""" knn = KNNClassifier() X_test = np.array([[2, 3]]) with self.assertRaises(ValueError): knn.predict(X_test) def test_predict_simple_case(self): """测试简单预测""" self.knn.fit(self.X_train, self.y_train) # 靠近类别0的样本 X_test = np.array([[1.2, 1.9]]) predictions = self.knn.predict(X_test) self.assertEqual(predictions[0], 0) # 靠近类别1的样本 X_test = np.array([[7, 9]]) predictions = self.knn.predict(X_test) self.assertEqual(predictions[0], 1) def test_predict_multiple_samples(self): """测试多个样本的预测""" self.knn.fit(self.X_train, self.y_train) X_test = np.array([ [1.2, 1.9], # 应该预测为0 [7, 9], # 应该预测为1 [0.8, 0.7] # 应该预测为0 ]) predictions = self.knn.predict(X_test) expected = np.array([0, 1, 0]) np.testing.assert_array_equal(predictions, expected) def test_score_method(self): """测试score方法""" self.knn.fit(self.X_train, self.y_train) # 创建测试集 X_test = np.array([ [1.2, 1.9], [7, 9], [0.8, 0.7], [8.5, 9.5] ]) y_test = np.array([0, 1, 0, 1]) accuracy = self.knn.score(X_test, y_test) self.assertEqual(accuracy, 1.0) # 所有预测都应该正确 # 测试有错误预测的情况 y_test_wrong = np.array([1, 0, 1, 0]) # 全部预测错误 accuracy = self.knn.score(X_test, y_test_wrong) self.assertEqual(accuracy, 0.0) def test_different_k_values(self): """测试不同的k值""" # k=1 knn1 = KNNClassifier(k=1) knn1.fit(self.X_train, self.y_train) # k=5 knn5 = KNNClassifier(k=5) knn5.fit(self.X_train, self.y_train) X_test = np.array([[3, 4]]) pred1 = knn1.predict(X_test) pred5 = knn5.predict(X_test) # k值不同,预测结果可能不同 # 这里我们只测试是否能正常预测 self.assertIn(pred1[0], [0, 1]) self.assertIn(pred5[0], [0, 1]) if __name__ == '__main__': unittest.main()

3. 使用体验分享

经过一周的密集测试,我对SmallThinker-3B-Preview有了比较全面的了解。下面分享一些实际使用中的感受。

3.1 生成速度

作为一个小模型,SmallThinker的生成速度确实很快。在我的测试环境中(RTX 3060 GPU),生成一个中等复杂度的函数加上测试用例,通常只需要3-5秒。这对于日常开发来说完全够用,不会打断编码的流畅性。

3.2 代码质量评估

我让SmallThinker生成了大约50个不同的函数和对应的测试用例,然后手动评估了它们的质量:

  • 语法正确性:95%的代码可以直接运行,不需要修改
  • 逻辑正确性:大约85%的算法实现逻辑正确
  • 测试覆盖率:生成的测试用例通常能覆盖80%以上的代码路径
  • 代码风格:符合PEP8规范,变量命名合理,注释适当

对于一个小模型来说,这个表现已经相当不错了。

3.3 实际应用场景

在实际工作中,我发现SmallThinker特别适合这些场景:

  1. 快速原型开发:当你需要快速验证一个想法时,让SmallThinker生成基础代码框架
  2. 单元测试编写:即使你自己写了函数,也可以让SmallThinker帮你生成测试用例
  3. 算法学习辅助:学习新算法时,让模型生成实现代码和测试用例,然后自己分析理解
  4. 代码审查辅助:用SmallThinker生成一个函数的多个实现版本,对比不同实现的优缺点

4. 效果分析与总结

4.1 技术亮点

SmallThinker-3B-Preview在代码生成方面有几个特别值得称赞的地方:

代码与测试的协同生成大多数代码生成模型只关注生成代码本身,而SmallThinker能够同时生成高质量的测试用例。这种"代码+测试"的完整解决方案在实际开发中价值很大。

对边界情况的考虑生成的测试用例通常能很好地覆盖边界情况,比如空输入、极端值、类型错误等。这说明模型在训练时接触过高质量的测试代码数据。

代码可读性生成的代码结构清晰,变量命名合理,注释适当。这对于代码维护和团队协作很重要。

4.2 局限性分析

当然,SmallThinker也有一些局限性:

复杂算法可能出错对于特别复杂的算法或业务逻辑,生成的代码可能需要人工调整。模型有时会忽略一些细节或边界条件。

长代码生成能力有限由于模型规模较小,生成非常长的代码文件时,可能会出现逻辑不连贯的情况。

特定领域知识不足对于需要特定领域知识的代码(如金融计算、科学计算等),模型的表现可能不如通用编程任务。

4.3 使用建议

基于我的测试经验,给想要尝试SmallThinker的朋友一些建议:

  1. 明确需求描述:在提问时尽量详细地描述需求,包括输入输出、边界条件、性能要求等
  2. 分步生成:对于复杂功能,可以分步骤生成,先让模型生成核心函数,再生成辅助函数
  3. 人工审查:生成的代码一定要人工审查,特别是涉及安全或关键业务的代码
  4. 结合使用:可以把SmallThinker作为编码助手,而不是完全依赖它

5. 总结

SmallThinker-3B-Preview给我带来了不小的惊喜。作为一个只有3B参数的小模型,它在代码生成和测试用例生成方面的表现超出了我的预期。虽然它不能完全替代程序员的思考,但作为一个高效的编码助手,它确实能显著提升开发效率。

最让我印象深刻的是它生成单元测试用例的能力。写测试往往是开发中最枯燥的部分,但又是保证代码质量的关键。SmallThinker能自动生成高质量的测试用例,这为开发者节省了大量时间。

如果你经常需要写Python代码,特别是需要写大量单元测试的项目,我强烈建议你试试SmallThinker。它可能不会每次都生成完美的代码,但至少能给你一个很好的起点。而且随着模型的不断优化,我相信它的表现会越来越好。

对于开源社区来说,SmallThinker这样的模型也很有意义。它证明了小模型也能在特定任务上表现出色,这为资源受限的环境提供了更多可能性。无论是边缘设备部署,还是作为大模型的草稿模型,SmallThinker都展现出了实用价值。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/3 22:29:53

全能型跨平台Unity资源编辑器:UABEAvalonia效率倍增指南

全能型跨平台Unity资源编辑器&#xff1a;UABEAvalonia效率倍增指南 【免费下载链接】UABEA UABEA: 这是一个用于新版本Unity的C# Asset Bundle Extractor&#xff08;资源包提取器&#xff09;&#xff0c;用于提取游戏中的资源。 项目地址: https://gitcode.com/gh_mirrors…

作者头像 李华
网站建设 2026/3/5 16:06:05

影墨·今颜效果展示:堪比单反的AI生成人像作品集

影墨今颜效果展示&#xff1a;堪比单反的AI生成人像作品集 如果你还在为AI生成的人像照片总有一种“塑料感”而烦恼&#xff0c;觉得它们不够真实、缺乏质感&#xff0c;那么今天这篇文章可能会彻底改变你的看法。我最近深度体验了一款名为“影墨今颜”的AI影像系统&#xff0…

作者头像 李华
网站建设 2026/3/4 4:54:49

人脸识别实战:Retinaface+CurricularFace镜像快速上手指南

人脸识别实战&#xff1a;RetinafaceCurricularFace镜像快速上手指南 你是不是也经历过这样的时刻&#xff1a;刚下载完一个人脸识别模型&#xff0c;还没开始跑代码&#xff0c;就卡在了环境配置上&#xff1f;PyTorch版本和CUDA驱动不兼容、模型权重路径不对、依赖包冲突报错…

作者头像 李华
网站建设 2026/3/4 0:17:32

Nano-Banana拆解引擎:手把手教你做专业部件展示图

Nano-Banana拆解引擎&#xff1a;手把手教你做专业部件展示图 在产品设计、技术教学和电商展示领域&#xff0c;一张清晰、专业的部件拆解图往往胜过千言万语。它能直观展示产品的内部结构、核心组件和组装逻辑&#xff0c;无论是用于产品说明书、维修指南还是营销素材&#x…

作者头像 李华
网站建设 2026/3/6 12:58:11

新手友好:Qwen3-ASR-0.6B语音识别系统搭建教程

新手友好&#xff1a;Qwen3-ASR-0.6B语音识别系统搭建教程 1. 引言&#xff1a;让机器听懂你的声音 你有没有想过&#xff0c;让电脑或手机像人一样听懂你说的话&#xff1f;无论是想把会议录音转成文字&#xff0c;还是想给视频自动加字幕&#xff0c;或者只是想用语音控制你…

作者头像 李华