搜尋
首頁後端開發Python教學在生產應用程式中整合大型語言模型

在本實用指南中,您將學習如何為您的應用程式建立具有內建 LLM 的高度可擴展的模型部署解決方案。
在您的範例中,我們將使用 Hugging Face 的 ChatGPT2 模型,但您可以輕鬆插入任何其他模型,包括 ChatGPT4、Claude 等。
無論您是設計具有 AI 功能的新應用程序,還是改進現有的 AI 系統,本指南都將幫助您逐步創建強大的 LLM 整合。

了解 LLM 整合基礎知識

在開始編寫程式碼之前,讓我們先弄清楚建置生產 LLM 整合需要什麼。在建立生產就緒的 LLM 整合時,API 呼叫並不是您需要考慮的唯一事情,您還需要考慮可靠性、成本和穩定性等問題。您的生產應用程式必須解決服務中斷、速率限制和回應時間變化等問題,同時控製成本。
這是我們將共同建構的內容:

  • 一個強大的 API 用戶端,可以優雅地處理失敗
  • 用於最佳化成本和速度的智慧型快取系統
  • 適當的提示管理系統
  • 全面的錯誤處理與監控
  • 完整的內容審核系統作為您的範例項目

先決條件

在我們開始編碼之前,請確保您擁有:

  • 您的電腦上安裝了 Python 3.8 或更高版本
  • Redis雲端帳號或本地安裝
  • 基礎Python程式設計知識
  • REST API 的基本了解
  • Hugging Face API 金鑰(或任何其他 LLM 提供者金鑰)

想跟隨嗎?完整的程式碼可以在您的 GitHub 儲存庫中找到。

設定您的開發環境

讓我們先準備好您的開發環境。我們將創建一個乾淨的專案結構並安裝所有必要的軟體包。

首先,讓我們建立專案目錄並設定 Python 虛擬環境。開啟終端機並運作:

mkdir llm_integration && cd llm_integration
python3 -m venv env
syource env/bin/activate

現在讓我們設定您的專案依賴項。使用這些基本套件建立一個新的requirements.txt 檔案:

transformers==4.36.0
huggingface-hub==0.19.4
redis==4.6.0
pydantic==2.5.0
pydantic-settings==2.1.0
tenacity==8.2.3
python-dotenv==1.0.0
fastapi==0.104.1
uvicorn==0.24.0
torch==2.1.0
numpy==1.24.3

讓我們來分析為什麼我們需要這些套件:

  • Transformers:這是 Hugging Face 強大的函式庫,我們將用它來與 Qwen2.5-Coder 模型進行互動。
  • Huggingface-hub:使我們能夠處理模型載入和版本控制 redis:用於實現請求快取
  • pydantic:用於資料驗證和設定。
  • 堅韌:負責重試功能以提高可靠性
  • python-dotenv:用於載入環境變數
  • fastapi:使用少量程式碼建立您的 API 端點
  • uvicorn:用於高效運行 FastAPI 應用程式
  • torch:用於運行變壓器模型和處理機器學習操作
  • numpy:用於數值計算。

使用以下指令安裝所有軟體套件:

mkdir llm_integration && cd llm_integration
python3 -m venv env
syource env/bin/activate

讓我們以乾淨的結構來組織您的專案。在您的專案目錄中建立這些目錄和檔案:

transformers==4.36.0
huggingface-hub==0.19.4
redis==4.6.0
pydantic==2.5.0
pydantic-settings==2.1.0
tenacity==8.2.3
python-dotenv==1.0.0
fastapi==0.104.1
uvicorn==0.24.0
torch==2.1.0
numpy==1.24.3

建置 LLM 客戶端

讓我們從您的LLM客戶端開始,這是您申請中最重要的組成部分。這是我們與 ChatGPT 模型(或您喜歡的任何其他 LLM)互動的地方。將以下程式碼片段加入您的 core/llm_client.py 檔案:

pip install -r requirements.txt

在 LLMClient 類別的第一部分中,我們正在建立基礎:

  • 我們正在使用 Transformer 庫中的 AutoModelForCausalLM 和 AutoTokenizer 來載入您的模型
  • device_map="auto" 參數自動處理 GPU/CPU 分配
  • 我們使用 torch.float16 來最佳化記憶體使用,同時保持良好的效能

現在讓我們加入與您的模型對話的方法:

llm_integration/
├── core/
│   ├── llm_client.py      # your main LLM interaction code
│   ├── prompt_manager.py  # Handles prompt templates
│   └── response_handler.py # Processes LLM responses
├── cache/
│   └── redis_manager.py   # Manages your caching system
├── config/
│   └── settings.py        # Configuration management
├── api/
│   └── routes.py          # API endpoints
├── utils/
│   ├── monitoring.py      # Usage tracking
│   └── rate_limiter.py    # Rate limiting logic
├── requirements.txt
└── main.py
└── usage_logs.json       

讓我們分解一下這個完成方法中發生了什麼:

  • 新增了@retry裝飾器方法來處理臨時失敗。
  • 使用 torch.no_grad() 上下文管理器透過停用梯度計算來節省記憶體。
  • 追蹤輸入和輸出中的令牌使用情況,這對於成本計算非常重要。
  • 傳回包含回應和使用統計資訊的結構化字典。

建立您的 LLM 回應處理程序

接下來,我們需要加入回應處理程序來解析和建構 LLM 的原始輸出。使用下列程式碼片段在 core/response_handler.py 檔案中執行此操作:

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from tenacity import retry, stop_after_attempt, wait_exponential
from typing import Dict, Optional
import logging

class LLMClient:
    def __init__(self, model_name: str = "gpt2", timeout: int = 30):
        try:
            self.tokenizer = AutoTokenizer.from_pretrained(model_name)
            self.model = AutoModelForCausalLM.from_pretrained(
                model_name,
                device_map="auto",
                torch_dtype=torch.float16
            )
        except Exception as e:
            logging.error(f"Error loading model: {str(e)}")
            # Fallback to a simpler model if the specified one fails
            self.tokenizer = AutoTokenizer.from_pretrained("gpt2")
            self.model = AutoModelForCausalLM.from_pretrained("gpt2")

        self.timeout = timeout
        self.logger = logging.getLogger(__name__)

添加強大的緩存系統

現在讓我們建立您的快取系統來提高應用程式效能並降低成本。將以下程式碼片段加入您的cache/redis_manager.py 檔案:

 @retry(
        stop=stop_after_attempt(3),
        wait=wait_exponential(multiplier=1, min=4, max=10),
        reraise=True
    )
    async def complete(self, 
                      prompt: str, 
                      temperature: float = 0.7,
                      max_tokens: Optional[int] = None) -> Dict:
        """Get completion from the model with automatic retries"""
        try:
            inputs = self.tokenizer(prompt, return_tensors="pt").to(
                self.model.device
            )

            with torch.no_grad():
                outputs = self.model.generate(
                    **inputs,
                    max_new_tokens=max_tokens or 100,
                    temperature=temperature,
                    do_sample=True
                )

            response_text = self.tokenizer.decode(
                outputs[0], 
                skip_special_tokens=True
            )

            # Calculate token usage for monitoring
            input_tokens = len(inputs.input_ids[0])
            output_tokens = len(outputs[0]) - input_tokens

            return {
                'content': response_text,
                'usage': {
                    'prompt_tokens': input_tokens,
                    'completion_tokens': output_tokens,
                    'total_tokens': input_tokens + output_tokens
                },
                'model': "gpt2"
            }

        except Exception as e:
            self.logger.error(f"Error in LLM completion: {str(e)}")
            raise

在上面的程式碼片段中,我們建立了一個 CacheManager 類,它透過以下方式處理所有快取操作:

  • _generate_key 方法,根據提示和參數建立唯一的快取鍵
  • get_cached_response 檢查我們是否有給定提示的快取回應
  • cache_response 儲存成功的回應以供將來使用

建立智慧型提示管理器

讓我們建立您的提示管理員來管理您的 LLM 模型的提示。將以下程式碼加入您的 core/prompt_manager.py 中:

mkdir llm_integration && cd llm_integration
python3 -m venv env
syource env/bin/activate

然後使用程式碼片段在您的提示/content_moderation.json 檔案中建立用於內容審核的範例提示範本:

transformers==4.36.0
huggingface-hub==0.19.4
redis==4.6.0
pydantic==2.5.0
pydantic-settings==2.1.0
tenacity==8.2.3
python-dotenv==1.0.0
fastapi==0.104.1
uvicorn==0.24.0
torch==2.1.0
numpy==1.24.3

現在,您的提示管理器將能夠從 JSON 檔案載入提示模板,並獲得格式化的提示模板。

設定配置管理器

為了將所有 LLM 配置保存在一個位置並輕鬆地在您的應用程式中重複使用它們,讓我們建立配置設定。將以下程式碼加入您的 config/settings.py 檔案:

pip install -r requirements.txt

實施速率限制

接下來,讓我們實施速率限制來控制使用者存取應用程式資源的方式。為此,請將以下程式碼新增至您的 utils/rate_limiter.py 檔案:

llm_integration/
├── core/
│   ├── llm_client.py      # your main LLM interaction code
│   ├── prompt_manager.py  # Handles prompt templates
│   └── response_handler.py # Processes LLM responses
├── cache/
│   └── redis_manager.py   # Manages your caching system
├── config/
│   └── settings.py        # Configuration management
├── api/
│   └── routes.py          # API endpoints
├── utils/
│   ├── monitoring.py      # Usage tracking
│   └── rate_limiter.py    # Rate limiting logic
├── requirements.txt
└── main.py
└── usage_logs.json       

在 RateLimiter 中,我們實作了一個可重複使用的 check_rate_limit 方法,該方法可在任何路由中使用,透過簡單地傳遞每個使用者在一段時間內允許的週期和請求數量來處理速率限制。

建立您的 API 端點

現在讓我們在 api/routes.py 檔案中建立 API 端點,以將 LLM 整合到您的應用程式中:

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from tenacity import retry, stop_after_attempt, wait_exponential
from typing import Dict, Optional
import logging

class LLMClient:
    def __init__(self, model_name: str = "gpt2", timeout: int = 30):
        try:
            self.tokenizer = AutoTokenizer.from_pretrained(model_name)
            self.model = AutoModelForCausalLM.from_pretrained(
                model_name,
                device_map="auto",
                torch_dtype=torch.float16
            )
        except Exception as e:
            logging.error(f"Error loading model: {str(e)}")
            # Fallback to a simpler model if the specified one fails
            self.tokenizer = AutoTokenizer.from_pretrained("gpt2")
            self.model = AutoModelForCausalLM.from_pretrained("gpt2")

        self.timeout = timeout
        self.logger = logging.getLogger(__name__)

這裡我們在 APIRouter 類別中定義了一個 /moderate 端點,它負責組織 API 路由。 @lru_cache 裝飾器應用於相依性注入函數(get_llm_client、get_response_handler、get_cache_manager 和 get_prompt_manager),以確保 LLMClient、CacheManager 和 PromptManager 的實例被快取以獲得更好的效能。以 @router.post 修飾的moderate_content函數定義了一個用於內容審核的POST路由,並利用FastAPI的Depends機制來注入這些依賴項。在函數內部,RateLimiter 類別使用設定中的速率限制設定進行配置,強制執行請求限制。

最後,讓我們更新您的 main.py 以將所有內容整合在一起:

 @retry(
        stop=stop_after_attempt(3),
        wait=wait_exponential(multiplier=1, min=4, max=10),
        reraise=True
    )
    async def complete(self, 
                      prompt: str, 
                      temperature: float = 0.7,
                      max_tokens: Optional[int] = None) -> Dict:
        """Get completion from the model with automatic retries"""
        try:
            inputs = self.tokenizer(prompt, return_tensors="pt").to(
                self.model.device
            )

            with torch.no_grad():
                outputs = self.model.generate(
                    **inputs,
                    max_new_tokens=max_tokens or 100,
                    temperature=temperature,
                    do_sample=True
                )

            response_text = self.tokenizer.decode(
                outputs[0], 
                skip_special_tokens=True
            )

            # Calculate token usage for monitoring
            input_tokens = len(inputs.input_ids[0])
            output_tokens = len(outputs[0]) - input_tokens

            return {
                'content': response_text,
                'usage': {
                    'prompt_tokens': input_tokens,
                    'completion_tokens': output_tokens,
                    'total_tokens': input_tokens + output_tokens
                },
                'model': "gpt2"
            }

        except Exception as e:
            self.logger.error(f"Error in LLM completion: {str(e)}")
            raise

在上面的程式碼中,我們使用 /api/v1 前綴下的 api.routes 建立了一個 FastAPI 應用程式和路由器。啟用日誌記錄以顯示帶有時間戳記的資訊訊息。該應用程式將使用 Uvicorn 運行 localhost:8000,並啟用熱重載。

運行您的應用程式

現在所有元件都已就位,讓我們開始啟動並運行您的應用程式。首先,在專案根目錄中建立一個 .env 檔案並新增您的 HUGGINGFACE_API_KEY 和 REDIS_URL:

mkdir llm_integration && cd llm_integration
python3 -m venv env
syource env/bin/activate

然後確保 Redis 正在您的電腦上運行。在大多數基於 Unix 的系統上,您可以使用以下命令啟動它:

transformers==4.36.0
huggingface-hub==0.19.4
redis==4.6.0
pydantic==2.5.0
pydantic-settings==2.1.0
tenacity==8.2.3
python-dotenv==1.0.0
fastapi==0.104.1
uvicorn==0.24.0
torch==2.1.0
numpy==1.24.3

現在您可以開始申請:

pip install -r requirements.txt

您的 FastAPI 伺服器將開始在 http://localhost:8000 上運作。自動 API 文件將在 http://localhost:8000/docs 上提供 - 這對於測試您的端點非常有幫助!

Integrating Large Language Models in Production Applications

測試您的內容審核 API

讓我們用真實的請求來測試您新建立的 API。開啟一個新終端機並執行以下curl指令:

llm_integration/
├── core/
│   ├── llm_client.py      # your main LLM interaction code
│   ├── prompt_manager.py  # Handles prompt templates
│   └── response_handler.py # Processes LLM responses
├── cache/
│   └── redis_manager.py   # Manages your caching system
├── config/
│   └── settings.py        # Configuration management
├── api/
│   └── routes.py          # API endpoints
├── utils/
│   ├── monitoring.py      # Usage tracking
│   └── rate_limiter.py    # Rate limiting logic
├── requirements.txt
└── main.py
└── usage_logs.json       

您應該在終端機上看到以下回應:

Integrating Large Language Models in Production Applications

新增監控和分析

現在讓我們加入一些監控功能來追蹤應用程式的執行情況以及正在使用的資源量。將以下程式碼加入您的 utils/monitoring.py 檔案:

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from tenacity import retry, stop_after_attempt, wait_exponential
from typing import Dict, Optional
import logging

class LLMClient:
    def __init__(self, model_name: str = "gpt2", timeout: int = 30):
        try:
            self.tokenizer = AutoTokenizer.from_pretrained(model_name)
            self.model = AutoModelForCausalLM.from_pretrained(
                model_name,
                device_map="auto",
                torch_dtype=torch.float16
            )
        except Exception as e:
            logging.error(f"Error loading model: {str(e)}")
            # Fallback to a simpler model if the specified one fails
            self.tokenizer = AutoTokenizer.from_pretrained("gpt2")
            self.model = AutoModelForCausalLM.from_pretrained("gpt2")

        self.timeout = timeout
        self.logger = logging.getLogger(__name__)

UsageMonitor 類別將執行以下操作:

  • 使用時間戳記追蹤每個 API 請求
  • 記錄代幣使用以進行成本監控
  • 測量反應時間
  • 將所有內容儲存在結構化日誌檔案中(在將應用程式部署到生產環境之前將其替換為資料庫)

接下來,新增一個新的方法來計算使用統計:

 @retry(
        stop=stop_after_attempt(3),
        wait=wait_exponential(multiplier=1, min=4, max=10),
        reraise=True
    )
    async def complete(self, 
                      prompt: str, 
                      temperature: float = 0.7,
                      max_tokens: Optional[int] = None) -> Dict:
        """Get completion from the model with automatic retries"""
        try:
            inputs = self.tokenizer(prompt, return_tensors="pt").to(
                self.model.device
            )

            with torch.no_grad():
                outputs = self.model.generate(
                    **inputs,
                    max_new_tokens=max_tokens or 100,
                    temperature=temperature,
                    do_sample=True
                )

            response_text = self.tokenizer.decode(
                outputs[0], 
                skip_special_tokens=True
            )

            # Calculate token usage for monitoring
            input_tokens = len(inputs.input_ids[0])
            output_tokens = len(outputs[0]) - input_tokens

            return {
                'content': response_text,
                'usage': {
                    'prompt_tokens': input_tokens,
                    'completion_tokens': output_tokens,
                    'total_tokens': input_tokens + output_tokens
                },
                'model': "gpt2"
            }

        except Exception as e:
            self.logger.error(f"Error in LLM completion: {str(e)}")
            raise

更新您的API以新增UsageMonitor類別中的監控功能:

from typing import Dict
import logging

class ResponseHandler:
    def __init__(self):
        self.logger = logging.getLogger(__name__)

    def parse_moderation_response(self, raw_response: str) -> Dict:
        """Parse and structure the raw LLM response for moderation"""
        try:
            # Default response structure
            structured_response = {
                "is_appropriate": True,
                "confidence_score": 0.0,
                "reason": None
            }

            # Simple keyword-based analysis
            lower_response = raw_response.lower()

            # Check for inappropriate content signals
            if any(word in lower_response for word in ['inappropriate', 'unsafe', 'offensive', 'harmful']):
                structured_response["is_appropriate"] = False
                structured_response["confidence_score"] = 0.9
                # Extract reason if present
                if "because" in lower_response:
                    reason_start = lower_response.find("because")
                    structured_response["reason"] = raw_response[reason_start:].split('.')[0].strip()
            else:
                structured_response["confidence_score"] = 0.95

            return structured_response

        except Exception as e:
            self.logger.error(f"Error parsing response: {str(e)}")
            return {
                "is_appropriate": True,
                "confidence_score": 0.5,
                "reason": "Failed to parse response"
            }

    def format_response(self, raw_response: Dict) -> Dict:
        """Format the final response with parsed content and usage stats"""
        try:
            return {
                "content": self.parse_moderation_response(raw_response["content"]),
                "usage": raw_response["usage"],
                "model": raw_response["model"]
            }
        except Exception as e:
            self.logger.error(f"Error formatting response: {str(e)}")
            raise

現在,透過執行以下curl 指令來測試您的 /stats 端點:

import redis
from typing import Optional, Any
import json
import hashlib

class CacheManager:
    def __init__(self, redis_url: str, ttl: int = 3600):
        self.redis = redis.from_url(redis_url)
        self.ttl = ttl

    def _generate_key(self, prompt: str, params: dict) -> str:
        """Generate a unique cache key"""
        cache_data = {
            'prompt': prompt,
            'params': params
        }
        serialized = json.dumps(cache_data, sort_keys=True)
        return hashlib.sha256(serialized.encode()).hexdigest()

    async def get_cached_response(self, 
                                prompt: str, 
                                params: dict) -> Optional[dict]:
        """Retrieve cached LLM response"""
        key = self._generate_key(prompt, params)
        cached = self.redis.get(key)
        return json.loads(cached) if cached else None

    async def cache_response(self, 
                           prompt: str, 
                           params: dict, 
                           response: dict) -> None:
        """Cache LLM response"""
        key = self._generate_key(prompt, params)
        self.redis.setex(
            key,
            self.ttl,
            json.dumps(response)
        )

上面的命令將向您顯示 /moderate 端點上的請求的統計信息,如下面的屏幕截圖所示:

Integrating Large Language Models in Production Applications

結論

透過本教程,我們學習如何在生產應用程式中使用大型語言模型。您實作了 API 用戶端、快取、提示管理和錯誤處理等功能。作為這些概念的範例,您開發了一個內容審核系統。

現在您已經有了堅實的基礎,您可以透過以下方式增強您的系統:

  • 即時應用程式的串流回應
  • A/B 測試以立即改進
  • 基於網路的介面來管理提示
  • 自訂模型微調
  • 與第三方監控服務整合

請記住,在範例中您使用了 ChatGPT2 模型,但您可以調整系統以與任何 LLM 提供者合作。因此,請選擇滿足您的要求且在預算之內的型號。

如果您有疑問或想告訴我您正在使用此系統建立什麼,請隨時與我聯繫。

編碼愉快! ?

以上是在生產應用程式中整合大型語言模型的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Python是否列表動態陣列或引擎蓋下的鏈接列表?Python是否列表動態陣列或引擎蓋下的鏈接列表?May 07, 2025 am 12:16 AM

pythonlistsareimplementedasdynamicarrays,notlinkedlists.1)他們areStoredIncoNtiguulMemoryBlocks,mayrequireRealLealLocationWhenAppendingItems,EmpactingPerformance.2)LinkesedlistSwoldOfferefeRefeRefeRefeRefficeInsertions/DeletionsButslowerIndexeDexedAccess,Lestpypytypypytypypytypy

如何從python列表中刪除元素?如何從python列表中刪除元素?May 07, 2025 am 12:15 AM

pythonoffersFourmainMethodStoreMoveElement Fromalist:1)刪除(值)emovesthefirstoccurrenceofavalue,2)pop(index)emovesanderturnsanelementataSpecifiedIndex,3)delstatementremoveselemsbybybyselementbybyindexorslicebybyindexorslice,and 4)

試圖運行腳本時,應該檢查是否會遇到'權限拒絕”錯誤?試圖運行腳本時,應該檢查是否會遇到'權限拒絕”錯誤?May 07, 2025 am 12:12 AM

toresolvea“ dermissionded”錯誤Whenrunningascript,跟隨台詞:1)CheckAndAdjustTheScript'Spermissions ofchmod xmyscript.shtomakeitexecutable.2)nesureThEseRethEserethescriptistriptocriptibationalocatiforecationAdirectorywherewhereyOuhaveWritePerMissionsyOuhaveWritePermissionsyYouHaveWritePermissions,susteSyAsyOURHomeRecretectory。

與Python的圖像處理中如何使用陣列?與Python的圖像處理中如何使用陣列?May 07, 2025 am 12:04 AM

ArraysarecrucialinPythonimageprocessingastheyenableefficientmanipulationandanalysisofimagedata.1)ImagesareconvertedtoNumPyarrays,withgrayscaleimagesas2Darraysandcolorimagesas3Darrays.2)Arraysallowforvectorizedoperations,enablingfastadjustmentslikebri

對於哪些類型的操作,陣列比列表要快得多?對於哪些類型的操作,陣列比列表要快得多?May 07, 2025 am 12:01 AM

ArraySaresificatificallyfasterthanlistsForoperationsBenefiting fromDirectMemoryAcccccccCesandFixed-Sizestructures.1)conscessingElements:arraysprovideconstant-timeaccessduetocontoconcotigunmorystorage.2)iteration:araysleveragececacelocality.3)

說明列表和數組之間元素操作的性能差異。說明列表和數組之間元素操作的性能差異。May 06, 2025 am 12:15 AM

ArraySareBetterForlement-WiseOperationsDuetofasterAccessCessCessCessCessCessCessCessAndOptimizedImplementations.1)ArrayshaveContiguucuulmemoryfordirectAccesscess.2)列出sareflexible butslible butslowerduetynemicizing.3)

如何有效地對整個Numpy陣列進行數學操作?如何有效地對整個Numpy陣列進行數學操作?May 06, 2025 am 12:15 AM

在NumPy中进行整个数组的数学运算可以通过向量化操作高效实现。1)使用简单运算符如加法(arr 2)可对数组进行运算。2)NumPy使用C语言底层库,提升了运算速度。3)可以进行乘法、除法、指数等复杂运算。4)需注意广播操作,确保数组形状兼容。5)使用NumPy函数如np.sum()能显著提高性能。

您如何將元素插入python數組中?您如何將元素插入python數組中?May 06, 2025 am 12:14 AM

在Python中,向列表插入元素有兩種主要方法:1)使用insert(index,value)方法,可以在指定索引處插入元素,但在大列表開頭插入效率低;2)使用append(value)方法,在列表末尾添加元素,效率高。對於大列表,建議使用append()或考慮使用deque或NumPy數組來優化性能。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。