Home小白的AI编程提效课
小白的AI编程提效课

小白的AI编程提效课

@峰兄

本专栏由小米、百度、阿里等互联网大厂的AI业务相关高管共创,专注于普通人的AI提效,提高程序员群体的开发效率。
v:hehan2048

小册包括六个专栏:AI编程实战、AI编程工具、AI高效办公、AI副业赚钱、AI提示词工程、AI私人助手

小册是永久买断制,原价 199 元,限时特惠 16.6 元买断制,满 3500 订阅涨为 28.8 元

承诺一年内更新50篇以上,一周至更新一篇内容。

买过后,从置顶帖【必看合集】,加入 AI 陪伴社群,限时领取超值福利。
订阅3599
文章35
最后更新:2024-2-3 11:11
查看 【小白的AI编程提效课】 详情查看 【峰兄】 主页
分享到微信打开

免费内容

2023-12-15 9:47

半小时,帮你实现一个AI版“图片搜索引擎”

一、技术方案一)概览我们都知道搜索引擎「百度」,「谷歌」可以搜索互联网上的所有文字内容。搜索引擎对结构化的数据可以识别的非常精准,但是对于非结构化的数据,比如图片,视频,音频却无能为力。下面这个百度搜索出的图片也是根据图片下面的文字构建的索引,是搜不出图片内的信息的。比如我是个自媒体作者想要引用电影中某个片段,直接用传统搜索引擎完全不行。AI时代这里就需要新一代的搜索引擎了。Embedding登场,它可以把所有非结构化数据统一转化为向量,进行向量搜索进行包含语义的查找。关于什么是RAG和Embedding就不赘述了,之前这篇讲的很详细:https://mp.weixin.qq.com/s/Onn5AiwZBenvPHxIyYoIXgRAG搜索引擎公式:语料+EmbeddingModel+向量库+LLM(可选)=搜索引擎图片文件+图片EmbeddingModel+向量库=图片搜索引擎视频文件+视频EmbeddingModel+向量库=视频搜索引擎音乐文件+音乐EmbeddingModel+向量库=音乐搜索引擎其他垂直行业,比如人脸识别,专利文件,病毒特征,只要训练好对应的EmbeddingModel都可以实对应的搜索引擎。本次就采用上述的技术方案来完成图片搜索引擎的功能。拆分成下面几步:选型EmbeddingModel,选型向量库,代码编写,代码示例。二)Embedding Model选型Embedding 是一个浮点数向量(列表)。两个向量之间的距离测量它们的相关性。较小的距离表示高相关性,较大的距离表示低相关性。简单来说就是把所有非结构化数据转化成可以让计算机理解的有语义的数据。图片Embedding,只会调用openai接口可搞不定了,需要本地运行模型了。这就不得不了解huggingface这个神器了。huggingface图片分类相关模型:https://huggingface.co/models?pipeline_tag=zero-shot-image-classification我们还是用老大哥openai的[clip](https://openai.com/research/clip)模型试试水。暂时就用最新的,且资源占用不太多的[openai/clip-vit-base-patch16](https://huggingface.co/openai/clip-vit-base-patch16)。三)向量库技术选型向量数据库简单来说就是用来存储向量,查询向量的数据库。1.专用向量数据库这些数据库从一开始就设计用于处理和检索向量数据,专门为高效的向量搜索和机器学习应用优化。Milvus优点: 高效的向量检索,适合大规模数据集。缺点: 相对较新,社区和资源可能不如成熟的传统数据库丰富。Weaviate优点: 支持图结构和自然语言理解,适用于复杂查询。缺点: 作为新兴技术,可能存在稳定性和成熟度方面的问题。2.传统数据库的向量扩展这些是传统数据库,通过扩展或插件支持向量数据的存储和检索。Elasticsearch优点: 强大的全文搜索功能,大型社区支持。缺点: 向量搜索可能不如专用向量数据库那么高效。PostgreSQL (使用PGVector或其他向量扩展)优点: 结合了传统的关系数据库强大功能和向量搜索。缺点: 向量搜索的性能和优化可能不及专用向量数据库。Redis优点: Redis是一种非常流行的开源内存数据结构存储系统,它以其高性能和灵活性而闻名。Redis通过模块如RedisAI和RedisVector支持向量数据,这使得它能够进行高速向量计算和近似最近邻(ANN)搜索,非常适合实时应用。缺点: 由于Redis主要是作为内存数据库,大规模的向量数据集可能会受到内存大小的限制。此外,它在处理大量复杂的向量操作方面可能不如专用向量数据库那样高效。3. 向量库的云服务这些服务提供了向量数据处理和搜索的云解决方案,通常易于扩展和维护。Pinecone优点: 易于扩展,无需管理基础设施,适合快速部署。缺点: 依赖于云提供商,可能存在成本和数据迁移方面的考虑。Amazon Elasticsearch Service优点: 完全托管,与AWS生态系统紧密集成。缺点: 可能涉及较高成本,且高度依赖AWS服务。对于我来说更倾向于使用传统数据库的向量扩展,比如这里我使用Redis+RedisSearch来实现向量库。因为企业级项目很多时候已经维护了一个大的Redis集群,而且很多云厂商也暂时不支持专用向量数据库。Redis官方对向量支持介绍:https://redis.com/blog/rediscover-redis-for-vector-similarity-search/二、代码实战一)技术架构分为导入和搜索两个流程。导入过程:把我们需要导入的一篮子图片集通过Clip转成向量,然后把向量导入Redis存储起来。搜索过程:搜索过程也是类似,把我们想要搜索的图片和文本同样使用Clip使用也进行向量化,然后去Redis中进行向量检索,就实现图片搜索引擎啦!二)准备图片既然是图片搜索引擎,当然得有海量图片了。处理多媒体文件的神器登场:FFmpeg1、安装ffmpeg官方下载链接:https://ffmpeg.org/download.htmlmac系统安装更简单,直接用homebrew安装brew install ffmpeg其他操作系统(linux,window)安装也比较简单,可以直接去官网下载。官方下载链接:https://ffmpeg.org/download.html2、生成图片我选了个自己比较喜欢的电影《楚门的世界》,把视频文件进行每秒抽帧来生成图片素材。ffmpeg -i Top022.楚门的世界.The.Truman.Show.1998.Bluray.1080p.x265.AAC\(5.1\).2Audios.GREENOTEA.mkv -r 1 truman-%3d.png经过一段时间的cpu飞速运转,得到了2000多张图片三)环境准备1、安装Python安装python的可以直接去官网https://www.python.org/downloads/英文不太好可以去看这个国人出的菜鸟教程https://www.runoob.com/python3/python3-install.html2、安装redis推荐使用docker安装redis,我们选用了7.2.0的新版本redisdocker-compose文件参考:version: "2.4" services: redis-server: image: redis/redis-stack-server:7.2.0-v6 container_name: redis-server ports: - 6379:6379 volumes: - ./redis-data:/data启动redisdocker-compose up -d四)图片向量化1、导入向量库指定我们图片的目录,把每张图片使用clip进行向量化,然后存入redis向量库中。import torch import numpy as np from transformers import CLIPProcessor, CLIPModel from PIL import Image import time import os import redis # 连接 Redis 数据库,地址换成你自己的 Redis 地址 client = redis.Redis(host="localhost", port=6379, decode_responses=True) res = client.ping() print("redis connected:", res) model_name_or_local_path = "openai/clip-vit-base-patch16" model = CLIPModel.from_pretrained(model_name_or_local_path) processor = CLIPProcessor.from_pretrained(model_name_or_local_path) # 换成你的图片目录 image_directory = "/Users/david/Downloads/turman" png_files = [filename for filename in os.listdir(image_directory) if filename.endswith(".png")] sorted_png_files = sorted(png_files, key=lambda x: int(x.split('-')[-1].split('.')[0])) # 初始化 Redis Pipeline pipeline = client.pipeline() for i, png_file in enumerate(sorted_png_files, start=1): # 初始化 Redis,先使用 PNG 文件名作为 Key 和 Value,后续再更新为图片特征向量 pipeline.json().set(png_file, "$", png_file) batch_size = 1 with torch.no_grad(): for idx, png_file in enumerate(sorted_png_files, start=1): print(f"{idx}: {png_file}") start = time.time() image = Image.open(f"{image_directory}/{png_file}") inputs = processor(images=image, return_tensors="pt", padding=True) image_features = model.get_image_features(inputs.pixel_values)[batch_size-1] embeddings = image_features.numpy().astype(np.float32).tolist() print('image_features:', embeddings) vector_dimension = len(embeddings) print('vector_dimension:', vector_dimension) end = time.time() print('%s Seconds'%(end-start)) # 更新 Redis 数据库中的文件向量 pipeline.json().set(png_file, "$", embeddings) res = pipeline.execute() print('redis set:', res)导入完成后可以看到,我们的2000多张图片都作为key转存储到redis中了。我们看到每个key的value都是512位的浮点数组,512位就代表我们向量的维度是512维,维度越高代表着存储的特征越多。import redis # 连接 Redis 数据库,地址换成你自己的 Redis 地址 client = redis.Redis(host="localhost", port=6379, decode_responses=True) res = client.ping() print("redis connected:", res) res = client.json().get("truman-1234.png") print(res) print(len(res))2、构建向量索引使用RedisSearch来把上面的向量构建索引。import redis from redis.commands.search.field import VectorField from redis.commands.search.indexDefinition import IndexDefinition, IndexType # 连接 Redis 数据库,地址换成你自己的 Redis 地址 client = redis.Redis(host="localhost", port=6379, decode_responses=True) res = client.ping() print("redis connected:", res) # 之前模型处理的向量维度是 512 vector_dimension = 512 # 给索引起个与众不同的名字 vector_indexes_name = "idx:truman_indexes" # 定义向量数据库的 Schema schema = ( VectorField( "$", "FLAT", { "TYPE": "FLOAT32", "DIM": vector_dimension, "DISTANCE_METRIC": "COSINE", }, as_name="vector", ), ) # 设置一个前缀,方便后续查询,也作为命名空间和可能的普通数据进行隔离 # 这里设置为 truman-,未来可以通过 truman-* 来查询所有数据 definition = IndexDefinition(prefix=["truman-"], index_type=IndexType.JSON) # 使用 Redis 客户端实例根据上面的 Schema 和定义创建索引 res = client.ft(vector_indexes_name).create_index( fields=schema, definition=definition ) print("create_index:", res)五)以图搜图激动人心的时刻到了,终于可以看到结果了!~运行下方代码import torch import numpy as np from transformers import CLIPProcessor, CLIPModel from PIL import Image import time import redis from redis.commands.search.query import Query model_name_or_local_path = "openai/clip-vit-base-patch16" model = CLIPModel.from_pretrained(model_name_or_local_path) processor = CLIPProcessor.from_pretrained(model_name_or_local_path) vector_indexes_name = "idx:truman_indexes" client = redis.Redis(host="localhost", port=6379, decode_responses=True) res = client.ping() print("redis connected:", res) start = time.time() image = Image.open("truman-173.png") batch_size = 1 with torch.no_grad(): inputs = processor(images=image, return_tensors="pt", padding=True) image_features = model.get_image_features(inputs.pixel_values)[batch_size-1] embeddings = image_features.numpy().astype(np.float32).tobytes() print('image_features:', embeddings) # 构建请求命令,查找和我们提供图片最相近的 5 张图片 query_vector = embeddings query = ( Query("(*)=>[KNN 5 @vector $query_vector AS vector_score]") .sort_by("vector_score") .return_fields("$") .dialect(2) ) # 定义一个查询函数,将我们查找的结果的 ID 打印出来(图片名称) def dump_query(query, query_vector, extra_params={}): result_docs = ( client.ft(vector_indexes_name) .search( query, { "query_vector": query_vector } | extra_params, ) .docs ) print(result_docs) for doc in result_docs: print(doc['id']) dump_query(query, query_vector, {}) end = time.time() print('%s Seconds'%(end-start))我们搜索跟这张图类似的5张图片。首先原图是被搜出来了,然后搜出特征相似的图片了,感觉还不错的样子。六)文字识图clip还具有识图能力,可以算出给出词数组和图片相似度的概率密度。这里给他一个图片和一组单词['dog', 'cat', 'night', 'astronaut', 'man', 'smiling', 'wave', 'smiling man wave'],让他给我算算。import torch from transformers import CLIPProcessor, CLIPModel from PIL import Image import time # 默认从 HuggingFace 加载模型,也可以从本地加载,需要提前下载完毕 model_name_or_local_path = "openai/clip-vit-base-patch16" # 加载模型 model = CLIPModel.from_pretrained(model_name_or_local_path) processor = CLIPProcessor.from_pretrained(model_name_or_local_path) # 记录处理开始时间 start = time.time() # 读取待处理图片 image = Image.open("truman-170.png") # 处理图片数量,这里每次只处理一张图片 batch_size = 1 # 要检测是否在图片中出现的内容 text = ['dog', 'cat', 'night', 'astronaut', 'man', 'smiling', 'wave', 'smiling man wave'] with torch.no_grad(): # 将图片使用模型加载,转换为 PyTorch 的 Tensor 数据类型 # 相比较第一篇文章中的例子 1.how-to-embededing/app.py,这里多了一个 text 参数 inputs = processor(text=text, images=image, return_tensors="pt", padding=True) # 将 inputs 中的内容解包,传递给模型,调用模型处理图片和文本 outputs = model(**inputs) # 将原始模型输出转换为类别概率分布(在类别维度上执行 softmax 激活函数) probs = outputs.logits_per_image.softmax(dim=1) end = time.time() # 记录处理结束时间 print('%s Seconds' % (end - start)) # 打印所有的概率分布 for i in range(len(text)): print(text[i], ":", probs[0][i])结果smiling man wave(微笑的男人挥手)这个词的概率最大,确实跟我们图片的特征一致。8.use-clip-detect-element git:(main) ✗ python app.py 0.247056245803833 Seconds dog : tensor(0.0072) cat : tensor(0.0011) night : tensor(0.0029) astronaut : tensor(0.0003) man : tensor(0.0200) smiling : tensor(0.0086) wave : tensor(0.0117) smiling man wave : tensor(0.9482)七)文字搜图把文字做Embedding,去redis做向量检索就可以实现文章搜图的能力了。import torch import numpy as np from transformers import CLIPProcessor, CLIPModel, CLIPTokenizer import time import redis from redis.commands.search.query import Query model_name_or_local_path = "openai/clip-vit-base-patch16" model = CLIPModel.from_pretrained(model_name_or_local_path) processor = CLIPProcessor.from_pretrained(model_name_or_local_path) # 处理文本需要引入 tokenizer = CLIPTokenizer.from_pretrained(model_name_or_local_path) vector_indexes_name = "idx:truman_indexes" client = redis.Redis(host="localhost", port=6379, decode_responses=True) res = client.ping() print("redis connected:", res) start = time.time() # 调用模型获取文本的 embeddings def get_text_embedding(text): inputs = tokenizer(text, return_tensors = "pt") text_embeddings = model.get_text_features(**inputs) embedding_as_np = text_embeddings.cpu().detach().numpy() embeddings = embedding_as_np.astype(np.float32).tobytes() return embeddings with torch.no_grad(): # 获取文本的 embeddings text_embeddings = get_text_embedding('Say hello') # text_embeddings = get_text_embedding('smiling man') query_vector = text_embeddings query = ( Query("(*)=>[KNN 5 @vector $query_vector AS vector_score]") .sort_by("vector_score") .return_fields("$") .dialect(2) ) def dump_query(query, query_vector, extra_params={}): result_docs = ( client.ft(vector_indexes_name) .search( query, { "query_vector": query_vector } | extra_params, ) .docs ) print(result_docs) for doc in result_docs: print(doc['id']) dump_query(query, query_vector, {}) end = time.time() print('%s Seconds'%(end-start))这是搜索smiling man的top5结果,确实是可以实现通过我们的语义进行搜索图片了!再搜索Say hello,也搜到了上面大笑打招呼的图片。三、总结完整代码链接:https://github.com/hehan-wang/simple-image-search-engineAI的快速发展可以让我们一个不是机器学习专业的也可以用模型做出一个有趣又有一些价值的AI项目。下面是我的几个启发1.学习AI从调接口开始,但不要只是调接口。调OPENAI的API是比较简单,上手快,可以快速做出一些案例。但不要把思维框在调接口里,Huggingface上还有大量好玩的模型,也不一定需要gpu,cpu上也可以玩起来,要多上手尝试,其实没想象中那么难。2.产品化我们这里只是投喂了一部电影,当我们投喂大量电影,并做出ui界面给普通用户使用,这里还是有很大商业价值的。更多内容可以点击目录:手册内容汇总✨ 如果觉得有收获,请点一点下方的“有启发” ✨🌱 我也会及时优化迭代内容,给大家更好的阅读体验 🌱

2023-11-19 19:20

借助GPT30分钟为2500家连锁店做了一套系统

今天接到一个连锁店朋友的需求,需求是这样的:门店里有一个电子屏设备,用来给客户展示门店售卖的产品,总部希望能控制屏幕上展示的商品,不然每个店里自己独立替换一方面很耗精力,另外总部也不好把控是否有没替换的门店。所以,他想在电子屏设备上安装一个浏览器,浏览器上展示一副图片,当总部服务器的图片库已更新,对应的终端设备上浏览器的图片也同步更新。其实这个需求本质上是非常简单的,我当时理解的是要做成下图这样:一个客户端,一个服务端,两端需要像微信那样双向通信,服务器监听一个文件中图片的变化,当上传新图片时,会触发相应的事件并发送到监听器中,读取图片,进行编码,通过websocket传到客户端,客户端进行解码,解出图片,展示到图片标签上。思路很清晰,不过我评估了一下,如果后端用php的swoole框架或者go语言写,怎么也要一天的时间,而我最近确实没这个时间。就在我左右为难时,突然想到了我的AI小助理:ChatGPT(以下简称C老师)。对呀,这么明确的需求,交给他是再合适不过了,于是乎就答应了下来,答应这周五给他,其实我从开始做到服务器部署好,也就半小时,真正让C老师帮我生成代码的时间也就10分钟。由于我一开始对这个问题理解的误区, 我先基于上面的方案让C老师给我相应的实现代码Round1:我先提问:我现在有一个需求,一个前端页面展示图片,图片是从后端返回的,后端图片变更后,前端立马变更为新的图片,前端可以使用js原生,后端使用php语言,通讯采用websocketC老师给了我四个步骤:后端使用 PHP 编写代码,在服务器上监听 WebSocket 通道,等待前端页面发送请求。前端使用 JavaScript WebSocket API,连接到后端的 WebSocket 服务器,并在需要时发送消息请求图片数据。当后端收到前端的请求后,查询最新的图片数据,并将二进制数据转换为 Base64 编码的字符串,在数据中添加图片类型和其他必要信息一同发送给前端。前端收到数据后,将 Base64 编码的字符串解码为二进制数据,并创建一个新的 URL 对象,将其赋值给页面上的图片元素的 src 属性即可。PS:跟我之前的思路是一致的,那就按照他的步骤一步步实现就行了Round2:我让C老师先帮我实现他给我建议的第一步:生成后端的代码C老师也给我生成了对应的代码,这里由于篇幅限制,就不贴代码了。使用php的swoole框架生成的代码Round3:我让C老师先帮我实现他给我建议的第二步:生成前端代码这是gpt生成的客户端使用websocket请求服务器的方法其实后面还有很多轮交互(篇幅原因,就不贴了),都是基于我一开始的方案实现的,基本上基于以上思路的代码都实现了。不过做了一会以后,我突然灵魂出窍了,不对,是开窍了,有必要搞的这么麻烦吗?这样服务器也要装一堆的服务。这个不就是前端浏览器每隔一个固定的时间去请求一下服务器上放的静态图片,不管图片有没有更新,都重新返回服务器的图片,对啊,就是浏览器定时轮训去请求服务器,仅此而已。好吧,现在需求的难度降到了0,不过让我自己写,没个两小时也搞不定,毕竟代码量在哪放着呢?肿么办,交给C老师继续吧,后面的就比较顺利了,不过也遇到了一点小坑。RoundN+1:我问C老师:请使用原生javascript实现功能:定时获取一张互联网的图片,更新页面上的图片链接PS:截图里有C老师给我生成的代码,其实做前端的朋友能看出这段代码是有点问题的,updateImage函数引用了外部的img变量,这里由于变量的作用域问题其实是获取不到img标签的,也就没办法给这个标签绑定图片地址,最终,运行页面时看到的就是不展示图片。这段代码其实有一点问题RoundN+2:我问:页面、样式我也懒得写,让C老师继续帮我生成页面代码让C老师帮我生成,设置图片全屏展示的样式:最终,我把C老师给我的前端代码进行了一下合并,简单删减了两行代码,运行了一下,没展示问题,后来排查到就是上面提到的变量局部作用域的问题,所以,要用好C老师,还是需要多多少少懂一点点代码的。然后从百度上下载了一张图片,放上去试了一下,可以展示,附上最终的前端代码和效果图:中间就是那个定时器,每隔30秒请求一次服务器,当服务器上有新的图片,就会替换到浏览器上的图片。 浏览器呈现的效果图至此,浏览器端搞定了,服务器上使用Nginx新建一个server,然后替换一下index.html首页,创建static文件夹存放图片,纯静态的一个服务器就搭建好了,真香!需要门店更新图片时,需要更新一下static文件夹中的图片,期待30S后门店客户端中的图片自动更新。结果客户端浏览器的图片没有更新,一想应该是Nginx开启了缓存配置,改一下配置,强制浏览器每次刷新都重新从服务器获取新图片这里问C老师如何关闭Nginx缓存功能然后替换Nginx的配置文件,重启Nginx使其生效后记:其实这个地方还可以做很多优化,比如前端做成轮播图的效果,后端可以上传多种图片。这种定时请求对服务器其实还是有一定压力的,不过因为毕竟请求的终端不多,最多也就2000台设备,而且是30S一次,所以这块服务器肯定是没问题的,就没有进一步优化了。中途其实是遇到了一点小小的困难的,不过还好,很快解决了,如果顺利的话,10分钟时间足够交付上面的小项目,所以C老师真的是我的良师益友,遇事不决,先问C老师!更多内容可以点击目录:手册内容汇总✨ 如果觉得有收获,请点一点下方的“有启发” ✨🌱 我也会及时优化迭代内容,给大家更好的阅读体验 🌱

2023-11-19 15:52

借助GPT10分钟完成业务模块全流程开发

一.前言首先,我们问一下GPT,软件开发的整体流程然后,我们找出其中核心的几步,借助GPT来辅助我们设计开发。这里我们以登录模块为例,因为大家都知道,一个软件或者系统也是由一个个的功能模块实现的,把一个功能模块实现了,其他的模块只是实现的功能不同,实现思路也是大同小异,如果一次性实现一个大的系统,由于涉及的内容过多,反而会没有重点,不利于大家的理解。这里我直接问GPT:我现在要做一个登录模块,希望你从需求分析、数据库建模、接口文档、代码实现、单元测试这五个方面分别描述一个登录模块需要实现的内容然后,针对每一部分单独提问,生成我们需要的内容二.需求分析针对以上内容中的需求分析部分,帮我生成一个登录模块的PRD,包括概述、用户使用流程、相关页面、功能详细描述、流程图、类图等。三.数据库建模针对上述内容中的数据库建模部分,我希望你针对登录模块的功能,按照业内数据库建模规范和最佳实践给我写一份数据库建模表格文档,包含表名、列名、数据类型、约束条件、描述、枚举值(用数字代替),ID不是自增,使用雪花ID算法生成,标准字段:create_time、update_time、deleted,我的数据库是MySQL8,相关的字段comment注释、表comment注释、需要建立索引的也需要加上,建表语句和索引语句也请告诉我。四.生成接口文档接口文档记录了API的用法和限制,确保客户端和服务器端正确地交互,提高代码重用性和可维护性。按照前面生成的表结构来分析,如果需要你设计一份标准的登录模块的基于RESTful接口文档,每一个接口都需要进行分析和论证必要性和设计合理性,请列出所需的接口。要求:返回OpenAPI规范JSON格式,描述信息需要中文以下是这些接口的OpenAPI规范JSON格式的一个示例概要: { "openapi": "3.0.0", "info": { "title": "登录模块API", "description": "为登录模块提供的RESTful API接口。", "version": "1.0.0" }, "paths": { "/login": { "post": { "summary": "用户登录", "description": "用户使用用户名和密码进行登录。", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "username": { "type": "string" }, "password": { "type": "string" } } } } } }, "responses": { "200": { "description": "登录成功" }, "401": { "description": "认证失败" } } } }, "/register": { "post": { "summary": "用户注册", "description": "新用户注册。", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "username": { "type": "string" }, "password": { "type": "string" }, "email": { "type": "string" } } } } } }, "responses": { "200": { "description": "注册成功" }, "400": { "description": "请求参数错误" } } } }, // 其他接口的定义类似 } } 五.完成后端服务接下来我们就进入开发环节,我希望的技术栈是使用PHP的laravel框架进行开发,你可以一步一步教我如何搭建一个项目吗?请帮我实现上述中的用户登录接口六.单元测试做过开发的朋友都知道,其实单元测试是非常耗费时间的一个环节。有时候开发一个功能可能1小时就能完成,但写单元测试可能会远超开发时间,现在有了GPT,单元测试就so easy了!针对上述的login方法,帮我写一个单元测试用例,要求:核心代码需要加上适当的中文注释。更多内容可以点击目录:手册内容汇总✨ 如果觉得有收获,请点一点下方的“有启发” ✨🌱 我也会及时优化迭代内容,给大家更好的阅读体验 🌱

2023-7-5 10:31

一文讲透GPT及如何正确的向GPT提问

从今年年初,OpenAI发布的ChatGPT已摧古拉朽之势席卷全球,短短两个月注册用户数就超过1亿人,是全世界增长速度最快的应用。你如果不聊两句ChatGPT,都不好意思出门。很多人都说今年是AI元年,其实也是有一定道理的,之前的AI门槛相对较高,很多人没有机会参与其中,而类ChatGPT的出现,把AIGC的门槛几乎降到了零,让普通人也可以参与到AI的浪潮中,一个人人可以AI创业的时代到来了!一.什么是ChatGPT?ChatGPT从字面上可以分解成两个词Chat+GPT。Chat是聊天的意思,GPT是Generative Pre-trained Transformer的缩写,生成式预训练语言模型,使用Transformer架构来处理自然语言处理(NLP)任务。也就是说GPT能理解自然语言,大家能够用汉语、英语等自然语言跟GPT交流,而且它有大量的训练语料,超大规模的训练参数(上千亿),能自己生成内容,并不是像搜索引擎一样只是简单的检索,就算一个它不知道的东西,它都可以根据已掌握的数据,生成一个答案,虽然有时候可能在胡说八道,从这个角度,确实已经很像人类了。总结一下就是,他有丰富的知识库,是一个知识渊博的智者,当你向他提问时,他能听懂你的提问,并且可以非常智能的生成答案(注意这里不是检索,所以你会发现每次向GPT提问同样的问题,得到的答案都是不一样的)PS:关于为什么向GPT提同样的问题得到不同的答案这个问题,这里我简单的说一下,GPT是一个深度神经网络,里面有几百亿甚至上千亿的参数,为了得到更多的发散性,每次可能走的神经网络不会完全相同,最终的结果就不会完全相同,所以你有时候会看到GPT在一本正经的胡说八道,可能也正是因为他的这个特点,让GPT看起来更像一个人吧。二.大模型发展这么久,为什么到GPT3.5才具有了真正的智能?大家通过上面的阅读知道,GPT(Generative Pre-trained Transformer)生成式预训练语言模型。也就是这个语言模型是基于Transformer的,Transformer是一种基于注意力机制的神经网络模型,最早由谷歌公司提出,其最初目的是用于自然语言处理任务,如机器翻译、文本摘要、语音识别等。相比于传统的循环神经网络模型,如LSTM和GRU,Transformer模型具有更好的并行化能力和更短的训练时间,在处理长序列任务方面表现出色,因此在自然语言处理领域得到了广泛应用。其实GPT不是OpenAI公司的原创,而是由谷歌公司发明。是不是跟当年操作系统的图形用户界面其实是施乐公司最新发明的,却被乔布斯窃取到并应用到苹果的系统上一样。包括后来的iphone手机,大家也可以搜一下,其实所有的设计都是借鉴了其他公司的产品,但是乔布斯把他们组合并创新成了一件最伟大的艺术品,从而开启了一个全新的移动互联网时代,所以有时候并不一定什么都要原创,站在巨人的肩膀上来微创新,有时候更容易出成果。上面扯的有点远了,我们回到为什么GPT3.5才算真正的人工智能这个问题上。2018 年 OpenAI 采用 Transformer Decoder 结构在大规模语料上训练了 GPT1 模型,揭开了NLP模型预训练+微调的新范式。2019 年,OpenAI 提出了 GPT2,GPT2 拥有和 GPT1 一样的模型结构,但得益于更多和更高的数据质量以及新引入的多任务学习方式,语言生成能力得到大幅提升。之后由于 GPT 采用 Decoder 单向结构天然缺陷是无法感知上下文,Google 很快提出了 Encoder 结构的 Bert 模型可以感知上下文,效果上也明显有提升,同年 Google 采用Encoder-Decoder 结构,提出了 T5 模型,从此大规模预训练语言模型朝着三个不同方向发展。也就是说在GPT3.0之前,谷歌的Bert 模型是远超OpenAI 的GPT模型的。这里补充一个知识点,GPT3.0之前都是开源的,OpenAI由于一些商业等多方面的考虑,从GPT3.5开始,模型都是闭源的。直到2020 年 OpenAI 提出了 GPT3 将 GPT 模型提升到全新的高度,其训练参数达到了 1750 亿,训练语料超45TB,自此GPT系列模型的数据飞轮便转动起来,超大模型时代开启, NLP 任务走向了预训练+情境学习新路线。由于 GPT3 可以产生通顺的句子,但是准确性等问题一直存在,于是出现了InstructGPT、ChatGPT 等后续优化的工作,通过加入强化学习模式实现了模型可以理解人类指令的含义,会甄别高水准答案,质疑错误问题和拒绝不适当的请求等。从GPT3.5,GPT突然涌现出了“乌鸦”能力,之前的都可以理解成量变,一种鹦鹉学舌的能力,并没有真正的智能。可能是大力出奇迹,我感觉跟人脑是一个道理,一个神经元没啥智慧,一百万个、一百亿个可能也没啥智慧,不过增加到一千亿个神经元连接,突然就有智慧了,涌现出了能力。这是一件很玄学的事情,包括现在世界顶级的人工智能专业也无法解释这种现象,我们只能理解成大力出奇迹。这里拿出一点篇幅来普及一下什么“鹦鹉学舌”的假人工智障,什么是拥有“乌鸦”能力的真人工智能所谓鹦鹉学舌,就是东施效颦。没有GPT之前,几乎所有的自然语言处理都遵循着这一范式。他没有真的懂你的意思,只是一种模式匹配,比如之前的语音助手,只能识别有限的场景,比如你问他,帮我导航去天安门,他可以给你答案,但如果你让问他火星怎么去,他可能就回答不了你,因为他的数据库里没有这个问题的答案。也就是说,他只能回答在自己的数据库里有对应答案的问题,一旦你的问题超出了他的数据范围,他是没办法给你回复的。无法做到根据现有的数据生成新的数据,但是世界的问题千千万,不可能穷尽所有的可能把所有的问题答案都事先准备好,这也是之前的人工智能大家感觉并不智能的原因,因为他的底层实际上还是在做匹配。我举一个程序员都能理解的例子,比如你要实现一个不同条件得到不同结果的功能,我相信大部分程序员都是这样实现的。 if($sex == '男' && $age < 18){ echo "小男孩"; }else if($sex == '女' && $age < 18){ echo "小女孩"; }else if($sex == '男' && $age >= 18 && $age <= 35){ echo "小伙子"; }else if($sex == '女' && $age >= 18 && $age <= 35){ echo "小姑娘"; }else{ echo "老年人"; }如果新增了条件,还是要新增一堆的if else才能匹配更多的情况。而乌鸦不一样,小时候我们读过乌鸦喝水的故事,乌鸦是有真正智慧的,他能真的读懂你要表达的意思。这里我们引用华人最厉害的AI学者之一朱松纯教授,在2017年写的一篇思考人工智能和智能本质的文章,通过这篇文章来理解乌鸦是如何感知、认知、推理、学习、执行的。乌鸦通过观察,自主串通了汽车能压碎坚果红绿灯能控制汽车车能撞死我这三件事情,从而利用红绿灯和汽车,来帮自己达到“安全打开坚果”这一任务结果。如果类比成机器学习模型,过往“鹦鹉学舌”范式的解法,是要求所有乌鸦可以共享一个大脑,它们有很清晰的优化目标,即“保住性命的前提下打开坚果”。它们的方式是,随机尝试所有事件的组合,并向着最优解的方向不断演化。但现实世界的乌鸦无法共享大脑,也不能去冒着死亡风险去尝试所有可能。乌鸦只有一次机会,把观测到的两个现象,产生了一个新的可能性,并应用在一个全新的场景下。这里最接近的词汇可能是“inference”,是“基于证据和逻辑推演,得到结论”的过程,有的时候,还要加入很多猜测、抽象、泛化。举个例子,这篇文章把朱教授对于乌鸦的比喻,跟ChatGPT最本质的能力联系起来,就是在做inferencing这件事。但很明显,inferencing不是乌鸦智能的全部。而且在机器学习领域里,inferencing特指使用训练好的深度学习模型来预测新的数据这一件事,会产生误解。其他词汇也有类似问题,所以我们在自己文章里,会直接使用“乌鸦能力”来指代ChatGPT的新能力。在对外交流时,我们没办法每次都把乌鸦能力是什么解释一遍,所以我们会用“理解”能力来进行指代。从“乌鸦”到“理解”,当然是一个信息量损失很大的过度概括。但是好处是可以把ChatGPT的本质能力凸显出来。过往互联网的两次能力跃进一次来自于搜索,一次来自于推荐,现在ChatGPT带来了“理解”,也非常有结构感。本节最后,再给大家看一张图,让大家了解ChatGPT是如何一步步演化到目前的水平的通过上图,大家可以看到:GPT-3.5通过InstructGPT的模式 + 阅读代码,涌现了“乌鸦”能力,产生了质变。但是还没找到合适的应用界面,也不符合人类喜好ChatGPT在RLHF的帮助下,找到了GPT-3.5和人类自然语言的合理接口,解锁了模型应用的前景(以上关于鹦鹉学舌和乌鸦能力的例子引用自"课代表立正的文章")这里解释几个专用名词:InstructGPT:ChatGPT的交互模式,让GPT的能力,更加贴近人类真实交互方式。在in-context learning基础之上,进一步降低了prompting的门槛;一定程度解决了GPT-3生成结果与用户期望不一致的非预期输出,大幅降低了有害的、错误或偏差的输出结果,让GPT更符合人类胃口RLHFChatGPT背后的核心技术之一,让模型学习人类的偏好。全称是reinforcement learning from human feedback,通过构建人类反馈数据集,训练一个reward模型,模仿人类偏好对结果打分,是GPT-3后时代LLM越来越像人类对话的核心技术ChatGPTInstructGPT的亲戚,但一些优化方式也带来了ChatGPT的更泛化和准确能力,再次引爆了AIGC。ChatGPT总体来说和InstructGPT一样是使用RLHF进行训练,但模型是基于GPT3.5,而且数据设置上也不同。ChatGPT是一个输入,模型给出多个输出,然后人给结果排序,让模型可以学习人类的排序策略,即使是一本正经的胡说八道看起来也很合理的样子三.如何与ChatGPT对话,Prompt 是什么?通过以上的内容,我们基本了解了ChatGPT是什么,以及他大概具有智能的原因。其实,我们最关心的并不是他多牛逼,而是,我如何才能借助这样的工具,为自身赋能、降本增效。如何与ChatGPT沟通交流呢,这里就要说到本文的重点Prompt了。遇事不决,先问GPT。我们先问一下ChatGPT,Prompt是什么?以上是ChatGPT的回答。我们来简单概括一下,Prompt 就是提示工程(Prompt Engineering)是指在使用自然语言处理(NLP)模型(例如 GPT-4)时,设计和优化输入文本(即提示)的过程。这一过程旨在更有效地引导模型生成所需的输出结果。提示工程的关键在于提高模型的表现,使其更准确、有趣或符合特定上下文要求。好了,那如何才能真正高效的与GPT沟通呢?让他能理解我们的问题,给出高质量的答案。就像与人沟通其实也是有很多技巧学问的,同样的,其实跟ChatGPT沟通也是有一些规律、模版是可以遵循的。四.如何向ChatGPT提问才能得到更加精准的回复我们向ChatGPT提问的目的就是为了得到想要的答案,很多朋友说GPT不好用,给的答案都是鸡肋,没有价值。大家有没有想过,这跟自己的提问技巧有关系呢?我们在生活中其实也会经常遇到一些不会提问的人,比如有些人在没交代任何背景的情况下,上来就问“如何成为一个有钱人”,让人不知道怎么答复。哪怕你问,作为一个刚毕业的大学生,如何在一个月时间挣到2W块这种问题,很多人也会给你一些建议。所以提问技巧是一个未来社会必备的技能,不光跟类GPT的AI进行交互需要,跟人交流其实也很有必要好好提升一下提问技巧。我们先来直接问问ChatGPT,如何提问才能得到高质量的答案ChatGPT列出了7条建议。其实网上关于Prompt优化的调教模版很多,我觉得说的都有道理,不过适合自己的才是最好的,大家可以在日常生活中根据自己的使用场景多去尝试,总结出适合自己的模版。网上关于ChatGPT的指令生成器非常多,比如ChatGPT指令大全:https://www.explainthis.io/zh-hans/chatgptChatGPT 快捷指令:https://www.aishort.top/我相对还是比较推荐台风大佬做的ChatGPT角色生成器这个网站https://role.aicosplay.com.cn/这里我也抛砖引玉,把市面上的模版做个简化,已经足够日常使用,还是那句话,只有自己实践的才是最适合自己的。我的Prompt优化调教模版主要包括四个方面1.角色在对话过程中,你希望GPT扮演什么角色,让他用一个专家的身份更加精准的回复你的问题2.背景发起指令的背景是什么?有利于ChatGPT更好的理解上下文相关信息3.任务你希望让GPT帮你干什么?你希望他如何解决你的问题4.要求你希望GPT用什么风格回复你、回复的内容的长度、内容的形式、有什么特殊要求等等下面,我们通过几个示例来学习如何使用上面的调教模版。五.通过具体示例来说明如何使用prompt优化调教模版我们先来一个全局的,让ChatGPT从上面的角色、背景、任务、要求四个维度来帮我们写几个Prompt调教示例以下是一些调教模版示例:示例一:你想让chatGPT充当用于翻译,可以这么说示例二:如果你要做表格,可以这么说:示例三:让chatGPT扮演一位心灵导师示例四:让chatGPT扮演一个文案写手示例五:AI佛祖六.其他一些需要注意的方面ChatGPT有上下文的概念,针对同一个问题,你可以连续的向ChatGPT一直提问,GPT会记住你之前的问题。基于这个特点,就要求我们一个对话场景,尽量单独开一个新的对话窗口,通过一个角色来跟GPT对话,以免不同的角色相互影响,导致GPT回答一些不相关的问题。及时给予ChatGPT反馈。告诉他,你是如何看待他给出的答案的。如果生成的不错,就夸一夸他,让他知道你喜欢他回复的内容;如果输出的内容不符合心意就告诉他,你不喜欢他的答案,并告诉他怎么去改进,让他继续给你生成想要的答案。你的每次反馈都决定了他接下来输出内容做如何微调。我们先随意让ChatGPT帮我们写一条小红书标题。大家看到写的非常一般,也不符合小红书的调用。所以,我们要批评他一下,让他按照我们的要求进行改进。这次改写后,感觉有点那个意思了。另外,如果你觉得回复的不错,也可以点那个大拇指给个赞,或者觉得回答的不好,点第二个大拇指给个踩,你的反馈,ChatGPT可以收到。3.逆向思维因为ChatGPT会对一些信息做屏蔽,所以你直接搜是搜不到了,这里不是教大家做错事,而是说有些时候我们确实需要某些信息,如果得不到的话,可以反其道而行之。比如,我直接问,北京的色情场所有哪些,ChatGPT是拒绝回答的。但是,我反向去问,感觉有点那个啥意思了😏六. 结束语当然还有很多技巧,不可能在一篇文章里全部面面俱到。不过,任何一个技巧、模版都不可能是万能的,很多时候,模版或技巧确实可以帮我们快速的达到及格线的水平,但是如果一直靠这些花里胡哨的东西,你永远也不可能成为一个行业顶尖的人才。很多东西是需要大家下苦功夫,在实战中一点点慢慢摸索出来的。实践才是检验真理的唯一标准。AI时代已来,面对每天海量的信息铺面而来,我想说,不要焦虑、不要担心自己会被替代,最好的方式就是保持一颗平常心,主动的拥抱AI,让AI成为你的个人助理,根据自身的情况,先从能马上提高自己工作生活效率的内容学起,躬身入局,日拱一卒,相信不久的将来,你一定会感谢今天的你的坚持!更多内容可以点击目录:手册内容汇总✨ 如果觉得有收获,请点一点下方的“有启发” ✨🌱 我也会及时优化迭代内容,给大家更好的阅读体验 🌱

2023-6-28 14:19

[必看合集] 小册使用指南

购买后第一步:加我微信 hehan2048,加入陪伴群。小册开启了合伙人计划,佣金高达60%,具体玩法可查看链接:合伙人计划!一.这个专栏想做什么?对于普通人,通过AI来给自己的工作、生活提效,不被时代淘汰针对程序员群体,如何通过AI赋能提高开发效率,迅速成为顶级开发者针对想做副业的朋友,如何借助AI发展自己的第二职业,并赚到第一桶金二.专栏快速导航蓝色字体已更新完毕,点击超链接即可跳转对应文章一)AI编程实战1. 借助GPT开发支撑上万并发的秒杀系统2. 借助GPT10分钟完成业务模块全流程开发3. 借助GPT30分钟为2500家连锁店做了一套系统4. 借助GPT帮助程序员解决线上系统问题5. 借助GPT帮助程序员快速学习其它语言6. 借助GPT小白不用一行代码就可以爬虫7. 借助百度文心一言10倍提升程序员工作效率8. 借助微软Bing十倍提升程序员工作效率9. 使用GPT生成专属学习教程10.零代码借助AI开发网页插件11. 抓住GPT插件生态红利 开发自己的GPT插件二)AI编程工具1. 编程小白也能用Copilot Chat开发一个网站2. 借助CodeGeeX等AI编程工具开发项目实战3. 21世纪的终端工具WARP4. AIGC数据库客户端Chat2DB三)AI高效办公1. 借助GPT一分钟读懂一篇英文论文2. 借助AI工具批量生成海报3. ChatGPT的平替版本Notion Al实战,干掉公司的文案4. 10分钟把一个想法变成精美PPT5. 批量填充模版类文档四)AI副业赚钱1. AI数字人从起号到变现2. AI公众号爆文写作变现全流程3. AI辅助企业培训,制作高质量培训课程4. AI+编程接单,一天赚了200多5. AI 绘画变现教程6. 微信表情包变现五)AI提示词工程1. 一文讲透GPT及如何正确的向GPT提问2. 文章总结生成摘要改写文章3. GPT 创意儿童成语学习工具的构想4. 甲方是真的难缠,应付甲方的 prompt5. Prompt深度总结长文的实操6. 逻辑差 ?表达差?Prompt 助你秒变高手7.GPT 创意儿童成语学习工具的构想六)AI私人助手1. OpenAI API进阶-Function Calling实现插件2. 基于RAG构建投喂大模型,实战与进阶3. 训练专属私有模型搭建企业知识库4. 基于RAG,三分钟制作飞书数字分身5. 使用LangChain,给你的GPT实时联网6. 使用llama_index,一分钟帮你读一本书7. 半小时,帮你实现一个AI版“图片搜索引擎”三.会员福利1.赠送国内版GPT网站月卡会员2.赠送大模型算力Token3.价值全网超全的AIGC资源包4.赠送GPT平替账号5.免费参加社群定期举行的各种线上线下活动欢迎加入AI陪伴群,群满加不上的话联系微信 hehan2048,备注【加群】拉你进入陪伴群。