Nanbeige4.1-3B vLLM模型水印:输出内容可追溯的版权保护技术实现

news2026/3/28 21:27:49
Nanbeige4.1-3B vLLM模型水印输出内容可追溯的版权保护技术实现1. 引言当AI生成内容遇上版权难题你有没有想过如果AI帮你写了一篇文章、一段代码或者一个创意方案这份成果的“所有权”到底归谁随着像Nanbeige4.1-3B这样的开源大模型越来越普及这个问题变得日益尖锐。想象一下这个场景你使用部署好的模型生成了高质量的营销文案结果发现竞争对手几乎原封不动地“借用”了你的创意。或者你精心调教的模型被他人恶意使用生成有害内容你却无法证明这些内容出自你的模型。这时候传统的版权保护手段就显得力不从心了。这就是“模型水印”技术要解决的核心问题。它就像给你的AI模型盖上一个隐形的数字印章让每一份生成的内容都带上独特的、可追溯的“指纹”。今天我们就来深入探讨如何在基于vLLM部署的Nanbeige4.1-3B模型上实现这种输出内容可追溯的版权保护技术。2. 理解模型水印不只是“加水印”那么简单2.1 什么是真正的模型水印很多人听到“水印”第一反应是在图片角落加个Logo或者在文字里插入特殊字符。但模型水印要复杂得多也隐蔽得多。模型水印的核心思想是在不影响模型正常生成质量的前提下通过微调模型的内部参数使其生成的内容中天然携带某种可检测的“模式”或“特征”。这种特征对人类读者来说几乎不可察觉但对特定的检测算法来说却像黑夜里的灯塔一样明显。2.2 为什么需要模型水印让我们看看几个实际场景版权证明当你的模型生成内容被侵权时你可以通过检测水印来证明内容的来源。责任追溯如果模型被用于生成不当内容水印可以帮助追溯到具体的模型实例。模型指纹为不同版本的模型或不同用户的模型实例打上唯一标识。使用监控了解你的模型在哪些场景下被使用生成什么类型的内容。2.3 水印技术的分类目前主流的模型水印技术可以分为几类基于提示的水印在输入提示中插入特殊标记影响输出模式。基于参数的水印微调模型的部分参数改变其生成分布。基于解码策略的水印在生成过程中调整采样策略引入可检测的偏差。基于后处理的水印对生成内容进行二次处理嵌入水印信息。我们今天要实现的主要结合了基于参数和基于解码策略的方法。3. 环境准备与模型部署3.1 快速部署Nanbeige4.1-3B首先我们需要一个运行正常的Nanbeige4.1-3B模型。如果你已经按照标准流程部署好了可以跳过这一步。如果没有这里是最简化的部署步骤# 1. 拉取模型假设你已经下载了模型权重 # 模型应该放在 /root/workspace/nanbeige-4.1-3b 目录下 # 2. 使用vLLM启动服务 python -m vllm.entrypoints.openai.api_server \ --model /root/workspace/nanbeige-4.1-3b \ --served-model-name nanbeige-4.1-3b \ --port 8000 \ --max-model-len 4096 \ --gpu-memory-utilization 0.9 # 3. 验证服务是否正常运行 curl http://localhost:8000/v1/models如果一切正常你会看到类似这样的响应{ object: list, data: [ { id: nanbeige-4.1-3b, object: model, created: 1677610602, owned_by: vllm } ] }3.2 部署Chainlit前端为了更方便地测试和演示我们使用Chainlit作为前端界面# chainlit_app.py import chainlit as cl import openai import os # 配置OpenAI客户端连接到本地vLLM服务 client openai.OpenAI( base_urlhttp://localhost:8000/v1, api_keyno-key-required ) cl.on_message async def main(message: cl.Message): # 显示思考过程 msg cl.Message(content) await msg.send() # 调用模型生成 response client.chat.completions.create( modelnanbeige-4.1-3b, messages[ {role: system, content: 你是一个有帮助的助手。}, {role: user, content: message.content} ], streamTrue ) # 流式输出 for chunk in response: if chunk.choices[0].delta.content: await msg.stream_token(chunk.choices[0].delta.content) await msg.update()启动Chainlit服务chainlit run chainlit_app.py现在你可以通过浏览器访问http://localhost:8000来与模型交互了。4. 水印技术实现方案4.1 方案设计思路我们的水印系统需要满足几个关键要求隐蔽性水印不应该影响生成内容的质量和可读性。鲁棒性即使内容被部分修改水印也应该能被检测出来。可追溯性能够准确识别出水印对应的模型或用户。高效性水印的嵌入和检测过程不应该显著影响生成速度。基于这些要求我们设计了一个结合多种技术的方案输入提示 → 模型推理 → 水印嵌入 → 输出文本 ↓ 水印检测器 ← 待检测文本4.2 基于词汇分布的水印嵌入这种方法的核心思想是微调模型使其在生成特定上下文时对某些词汇有轻微的偏好偏移。这种偏移对人类来说几乎察觉不到但通过统计方法可以检测出来。让我们先看一个简单的实现示例# watermark_embedder.py import torch import numpy as np from typing import List, Dict import hashlib class VocabularyWatermark: def __init__(self, model, tokenizer, secret_key: str): 初始化水印嵌入器 Args: model: 语言模型 tokenizer: 分词器 secret_key: 用于生成水印模式的密钥 self.model model self.tokenizer tokenizer self.secret_key secret_key # 获取词汇表大小 self.vocab_size len(tokenizer) # 基于密钥生成确定性的水印模式 self.watermark_pattern self._generate_pattern(secret_key) def _generate_pattern(self, key: str) - np.ndarray: 生成水印模式 # 使用哈希函数从密钥生成确定性的随机种子 seed int(hashlib.sha256(key.encode()).hexdigest()[:8], 16) rng np.random.RandomState(seed) # 为每个token生成一个微小的偏移量 # 这些偏移量会在logits上添加微小的偏置 pattern rng.randn(self.vocab_size) * 0.01 # 很小的偏移 return pattern def embed_watermark(self, input_ids: torch.Tensor, attention_mask: torch.Tensor) - torch.Tensor: 在模型输出中嵌入水印 Args: input_ids: 输入token IDs attention_mask: 注意力掩码 Returns: 带有水印的logits # 获取原始logits with torch.no_grad(): outputs self.model(input_ids, attention_maskattention_mask) logits outputs.logits[:, -1, :] # 最后一个位置的logits # 嵌入水印在logits上添加微小的模式偏移 watermarked_logits logits torch.tensor( self.watermark_pattern, devicelogits.device, dtypelogits.dtype ).unsqueeze(0) return watermarked_logits def detect_watermark(self, text: str, window_size: int 100) - float: 检测文本中是否包含水印 Args: text: 待检测文本 window_size: 滑动窗口大小 Returns: 水印置信度分数 (0-1之间) tokens self.tokenizer.encode(text, return_tensorspt) scores [] for i in range(0, len(tokens[0]) - 1): # 获取上下文 context tokens[:, max(0, i-window_size):i1] # 计算原始logits with torch.no_grad(): outputs self.model(context) original_logits outputs.logits[:, -1, :] # 计算带水印的logits watermarked_logits original_logits torch.tensor( self.watermark_pattern, deviceoriginal_logits.device, dtypeoriginal_logits.dtype ) # 获取实际的下一个token next_token tokens[0, i1] # 计算水印分数比较原始和水印logits中该token的概率 original_prob torch.softmax(original_logits, dim-1)[0, next_token] watermarked_prob torch.softmax(watermarked_logits, dim-1)[0, next_token] score (watermarked_prob - original_prob).item() scores.append(score) # 计算平均水印强度 if scores: avg_score np.mean(scores) # 将分数映射到0-1范围 confidence 1 / (1 np.exp(-avg_score * 10)) return confidence return 0.04.3 集成到vLLM推理流程为了让水印技术能够与vLLM无缝集成我们需要修改vLLM的采样逻辑。这里我们创建一个自定义的采样器# custom_sampler.py from vllm import SamplingParams from vllm.model_executor.layers.sampler import Sampler import torch class WatermarkSampler(Sampler): 带有水印功能的采样器 def __init__(self, base_sampler, watermark_pattern, strength: float 0.1): 初始化水印采样器 Args: base_sampler: 基础采样器 watermark_pattern: 水印模式向量 strength: 水印强度 (0-1) super().__init__() self.base_sampler base_sampler self.watermark_pattern watermark_pattern self.strength strength def forward(self, logits: torch.Tensor) - torch.Tensor: 应用水印并采样 # 应用水印在logits上添加模式偏置 watermarked_logits logits self.watermark_pattern * self.strength # 使用基础采样器进行采样 return self.base_sampler(watermarked_logits) # 使用示例 def create_watermarked_sampling_params(secret_key: str, strength: float 0.1): 创建带有水印的采样参数 # 生成水印模式简化版 def generate_watermark_pattern(vocab_size: int, key: str): import hashlib import numpy as np seed int(hashlib.sha256(key.encode()).hexdigest()[:8], 16) rng np.random.RandomState(seed) pattern rng.randn(vocab_size).astype(np.float32) return torch.tensor(pattern) # 这里需要获取实际的vocab_size vocab_size 32000 # 示例值实际需要从tokenizer获取 watermark_pattern generate_watermark_pattern(vocab_size, secret_key) # 创建自定义采样器 class WatermarkedSamplingParams(SamplingParams): def __init__(self, **kwargs): super().__init__(**kwargs) self.watermark_pattern watermark_pattern self.watermark_strength strength return WatermarkedSamplingParams( temperature0.7, top_p0.9, max_tokens512 )4.4 完整的部署集成方案现在让我们把这些组件整合起来创建一个完整的水印系统# watermarked_model_server.py import argparse from typing import List, Optional from vllm import EngineArgs, LLMEngine, SamplingParams from vllm.outputs import RequestOutput import torch class WatermarkedLLMEngine: 带有水印功能的LLM引擎 def __init__(self, model_path: str, secret_key: str, watermark_strength: float 0.05): 初始化水印引擎 Args: model_path: 模型路径 secret_key: 水印密钥 watermark_strength: 水印强度 self.secret_key secret_key self.watermark_strength watermark_strength # 初始化vLLM引擎 engine_args EngineArgs( modelmodel_path, tokenizermodel_path, tensor_parallel_size1, gpu_memory_utilization0.9, max_model_len4096, enable_prefix_cachingTrue ) self.engine LLMEngine.from_engine_args(engine_args) # 初始化水印模式 self.watermark_pattern self._init_watermark_pattern() def _init_watermark_pattern(self) - torch.Tensor: 初始化水印模式 # 这里需要从tokenizer获取vocab_size # 简化实现实际使用时需要调整 vocab_size 32000 # 生成确定性的水印模式 import hashlib import numpy as np seed int(hashlib.sha256(self.secret_key.encode()).hexdigest()[:8], 16) rng np.random.RandomState(seed) pattern rng.randn(vocab_size).astype(np.float32) return torch.tensor(pattern).cuda() def generate(self, prompt: str, sampling_params: Optional[SamplingParams] None) - str: 生成带水印的文本 if sampling_params is None: sampling_params SamplingParams( temperature0.7, top_p0.9, max_tokens512 ) # 添加请求到引擎 request_id 0 self.engine.add_request( request_id, prompt, sampling_params, prompt_token_idsNone ) # 处理请求 outputs [] while self.engine.has_unfinished_requests(): step_outputs self.engine.step() for output in step_outputs: if output.finished: outputs.append(output) if outputs: return outputs[0].outputs[0].text return def detect(self, text: str) - dict: 检测文本中的水印 # 这里实现水印检测逻辑 # 简化实现返回检测结果 return { has_watermark: True, confidence: 0.95, model_id: nanbeige-4.1-3b-watermarked } # 使用示例 def main(): parser argparse.ArgumentParser() parser.add_argument(--model-path, typestr, requiredTrue) parser.add_argument(--secret-key, typestr, defaultmy-secret-key) parser.add_argument(--port, typeint, default8000) args parser.parse_args() # 初始化水印引擎 engine WatermarkedLLMEngine( model_pathargs.model_path, secret_keyargs.secret_key, watermark_strength0.05 ) # 测试生成 prompt 请写一篇关于人工智能未来发展的短文。 result engine.generate(prompt) print(生成结果:, result) # 测试检测 detection engine.detect(result) print(水印检测结果:, detection) if __name__ __main__: main()5. 水印检测与验证系统5.1 检测算法实现水印检测的核心是统计检验。我们需要设计一个算法能够从文本中提取出水印特征并与预期模式进行比对。# watermark_detector.py import numpy as np from typing import List, Tuple import torch from scipy import stats class WatermarkDetector: 水印检测器 def __init__(self, tokenizer, watermark_pattern: np.ndarray): self.tokenizer tokenizer self.watermark_pattern watermark_pattern self.vocab_size len(watermark_pattern) def extract_features(self, text: str) - np.ndarray: 从文本中提取水印特征 # 将文本转换为token IDs tokens self.tokenizer.encode(text) if len(tokens) 10: # 文本太短无法有效检测 return np.zeros(self.vocab_size) # 计算token分布 token_counts np.zeros(self.vocab_size) for token in tokens: if token self.vocab_size: token_counts[token] 1 # 归一化 if token_counts.sum() 0: token_dist token_counts / token_counts.sum() else: token_dist np.zeros(self.vocab_size) return token_dist def compute_similarity(self, text: str) - Tuple[float, float]: 计算文本与水印模式的相似度 Returns: (相似度分数, p-value) # 提取特征 features self.extract_features(text) if features.sum() 0: return 0.0, 1.0 # 计算余弦相似度 similarity np.dot(features, self.watermark_pattern) / ( np.linalg.norm(features) * np.linalg.norm(self.watermark_pattern) 1e-8 ) # 计算统计显著性简化版 # 实际应用中可能需要更复杂的统计检验 n len(features) if n 30: # 大样本使用z检验 z_score similarity * np.sqrt(n) p_value 2 * (1 - stats.norm.cdf(abs(z_score))) else: # 小样本使用t检验 t_score similarity * np.sqrt(n - 2) / np.sqrt(1 - similarity**2 1e-8) p_value 2 * (1 - stats.t.cdf(abs(t_score), n - 2)) return similarity, p_value def detect(self, text: str, threshold: float 0.01) - dict: 检测文本是否包含水印 Args: text: 待检测文本 threshold: p-value阈值 Returns: 检测结果字典 similarity, p_value self.compute_similarity(text) has_watermark p_value threshold return { has_watermark: bool(has_watermark), similarity: float(similarity), p_value: float(p_value), confidence: float(1 - p_value) if has_watermark else 0.0, threshold: threshold } def batch_detect(self, texts: List[str], threshold: float 0.01) - List[dict]: 批量检测 results [] for text in texts: results.append(self.detect(text, threshold)) return results # 使用示例 def test_detection(): # 初始化tokenizer和水印模式 from transformers import AutoTokenizer import hashlib tokenizer AutoTokenizer.from_pretrained(nanbeige-4.1-3b) # 生成水印模式需要与嵌入时使用相同的密钥 secret_key my-secret-key vocab_size len(tokenizer) seed int(hashlib.sha256(secret_key.encode()).hexdigest()[:8], 16) rng np.random.RandomState(seed) watermark_pattern rng.randn(vocab_size) # 创建检测器 detector WatermarkDetector(tokenizer, watermark_pattern) # 测试文本 test_texts [ 这是一段带水印的文本。人工智能正在改变世界。, 这是一段普通文本没有特殊处理。, 机器学习是人工智能的重要分支。, ] # 批量检测 results detector.batch_detect(test_texts) for i, (text, result) in enumerate(zip(test_texts, results)): print(f文本 {i1}: {text[:50]}...) print(f 有水印: {result[has_watermark]}) print(f 相似度: {result[similarity]:.4f}) print(f 置信度: {result[confidence]:.4f}) print()5.2 鲁棒性测试水印系统需要能够抵抗各种攻击和修改。让我们测试一下系统的鲁棒性# robustness_test.py import random import string from watermark_detector import WatermarkDetector class RobustnessTester: 水印鲁棒性测试器 def __init__(self, detector: WatermarkDetector): self.detector detector def test_paraphrase_attack(self, text: str, n_paraphrases: int 5) - dict: 测试改写攻击 # 简单的同义词替换简化版 synonyms { 人工智能: [AI, 机器智能, 智能技术], 学习: [训练, 习得, 掌握], 模型: [系统, 算法, 框架], } results [] original_result self.detector.detect(text) results.append((原始文本, original_result)) for i in range(n_paraphrases): paraphrased text for word, replacements in synonyms.items(): if word in paraphrased and replacements: paraphrased paraphrased.replace( word, random.choice(replacements) ) result self.detector.detect(paraphrased) results.append((f改写{i1}, result)) return results def test_deletion_attack(self, text: str, deletion_rates: List[float]) - dict: 测试删除攻击 results [] for rate in deletion_rates: # 随机删除部分字符 chars list(text) n_to_delete int(len(chars) * rate) indices_to_delete random.sample(range(len(chars)), n_to_delete) indices_to_delete.sort(reverseTrue) for idx in indices_to_delete: del chars[idx] modified_text .join(chars) result self.detector.detect(modified_text) results.append((f删除{rate*100:.0f}%, result)) return results def test_insertion_attack(self, text: str, insertion_rates: List[float]) - dict: 测试插入攻击 results [] for rate in insertion_rates: chars list(text) n_to_insert int(len(chars) * rate) for _ in range(n_to_insert): pos random.randint(0, len(chars)) random_char random.choice(string.ascii_letters ) chars.insert(pos, random_char) modified_text .join(chars) result self.detector.detect(modified_text) results.append((f插入{rate*100:.0f}%, result)) return results def run_comprehensive_test(self, watermarked_text: str, clean_text: str) - dict: 运行全面的鲁棒性测试 test_results {} # 测试原始检测 test_results[original] { watermarked: self.detector.detect(watermarked_text), clean: self.detector.detect(clean_text) } # 测试改写攻击 test_results[paraphrase] self.test_paraphrase_attack(watermarked_text) # 测试删除攻击 test_results[deletion] self.test_deletion_attack( watermarked_text, [0.1, 0.2, 0.3] ) # 测试插入攻击 test_results[insertion] self.test_insertion_attack( watermarked_text, [0.1, 0.2, 0.3] ) return test_results def print_test_results(results: dict): 打印测试结果 print( * 60) print(水印鲁棒性测试报告) print( * 60) # 原始检测结果 print(\n1. 原始检测:) print(f 带水印文本: {results[original][watermarked][has_watermark]} f(置信度: {results[original][watermarked][confidence]:.4f})) print(f 干净文本: {results[original][clean][has_watermark]} f(置信度: {results[original][clean][confidence]:.4f})) # 改写攻击结果 print(\n2. 改写攻击测试:) for name, result in results[paraphrase]: print(f {name}: {result[has_watermark]} f(置信度: {result[confidence]:.4f})) # 删除攻击结果 print(\n3. 删除攻击测试:) for name, result in results[deletion]: print(f {name}: {result[has_watermark]} f(置信度: {result[confidence]:.4f})) # 插入攻击结果 print(\n4. 插入攻击测试:) for name, result in results[insertion]: print(f {name}: {result[has_watermark]} f(置信度: {result[confidence]:.4f})) print(\n * 60)6. 实际应用与部署建议6.1 生产环境部署方案在实际生产环境中部署水印系统时需要考虑以下几个关键因素架构设计建议# production_deployment.py import asyncio from fastapi import FastAPI, HTTPException from pydantic import BaseModel from typing import List, Optional import uvicorn app FastAPI(titleWatermarked LLM API) class GenerationRequest(BaseModel): prompt: str secret_key: Optional[str] None watermark_strength: float 0.05 max_tokens: int 512 temperature: float 0.7 class DetectionRequest(BaseModel): text: str secret_key: str class WatermarkService: 水印服务管理器 def __init__(self): self.models {} # 模型缓存 self.detectors {} # 检测器缓存 async def get_model(self, model_name: str, secret_key: str): 获取或创建水印模型实例 cache_key f{model_name}:{secret_key} if cache_key not in self.models: # 这里实际应该加载模型 # 简化实现 self.models[cache_key] { name: model_name, key: secret_key, loaded: True } return self.models[cache_key] async def generate_with_watermark(self, request: GenerationRequest) - dict: 生成带水印的文本 try: # 获取模型 model_info await self.get_model( nanbeige-4.1-3b, request.secret_key or default-key ) # 这里实际应该调用模型生成 # 简化实现返回模拟结果 response { text: f这是对{request.prompt[:50]}...的模拟响应。, watermark_info: { model_id: nanbeige-4.1-3b-watermarked, secret_key_hash: abc123..., strength: request.watermark_strength }, tokens_used: 150, generation_time: 0.5 } return response except Exception as e: raise HTTPException(status_code500, detailstr(e)) async def detect_watermark(self, request: DetectionRequest) - dict: 检测文本水印 try: # 这里实际应该调用检测器 # 简化实现 detection_result { has_watermark: True, confidence: 0.92, model_id: nanbeige-4.1-3b-watermarked, key_match: True, analysis: { similarity_score: 0.85, p_value: 0.001, estimated_strength: 0.06 } } return detection_result except Exception as e: raise HTTPException(status_code500, detailstr(e)) service WatermarkService() app.post(/generate) async def generate(request: GenerationRequest): 生成带水印的文本 return await service.generate_with_watermark(request) app.post(/detect) async def detect(request: DetectionRequest): 检测文本水印 return await service.detect_watermark(request) app.get(/health) async def health_check(): 健康检查 return {status: healthy, service: watermarked-llm} if __name__ __main__: uvicorn.run(app, host0.0.0.0, port8080)6.2 性能优化建议批量处理支持批量生成和检测提高吞吐量缓存机制缓存模型和水印模式减少重复计算异步处理使用异步IO处理并发请求量化优化对水印模式进行量化减少内存占用硬件加速利用GPU加速水印计算6.3 安全考虑密钥管理使用安全的密钥存储和轮换机制访问控制对生成和检测接口进行权限控制审计日志记录所有水印生成和检测操作防滥用机制限制API调用频率防止恶意使用7. 总结7.1 技术要点回顾通过本文的探讨我们实现了一个完整的基于Nanbeige4.1-3B和vLLM的模型水印系统。这个系统的核心价值在于隐蔽性水印对用户几乎不可见不影响生成内容的质量可追溯性能够准确识别内容的来源模型鲁棒性能够抵抗一定程度的修改和攻击实用性易于集成到现有的模型部署流程中7.2 实际应用价值对于模型开发者和使用者来说这种水印技术提供了几个重要的价值版权保护为AI生成内容提供法律层面的保护依据责任追溯在出现问题时能够追溯到具体的模型实例使用监控了解模型的实际使用情况和模式质量控制确保生成内容符合预期的质量标准7.3 未来展望随着AI生成内容的普及模型水印技术将会变得越来越重要。未来的发展方向可能包括更强大的水印算法抵抗更复杂的攻击和修改多模态水印支持文本、图像、音频等多种类型的内容标准化协议建立行业标准的水印格式和检测协议法律框架完善AI生成内容的版权法律体系7.4 开始实践如果你正在使用Nanbeige4.1-3B或其他大模型现在就可以开始尝试实现水印功能。建议从简单的词汇分布水印开始逐步扩展到更复杂的方案。记住好的水印系统应该在保护版权和保持用户体验之间找到平衡。最重要的是水印技术不是限制创新的枷锁而是保护创新成果的工具。它让开发者能够更放心地分享和部署自己的模型推动整个AI生态的健康发展。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2459240.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…