丁香五月天婷婷久久婷婷色综合91|国产传媒自偷自拍|久久影院亚洲精品|国产欧美VA天堂国产美女自慰视屏|免费黄色av网站|婷婷丁香五月激情四射|日韩AV一区二区中文字幕在线观看|亚洲欧美日本性爱|日日噜噜噜夜夜噜噜噜|中文Av日韩一区二区

您正在使用IE低版瀏覽器,為了您的雷峰網(wǎng)賬號(hào)安全和更好的產(chǎn)品體驗(yàn),強(qiáng)烈建議使用更快更安全的瀏覽器
此為臨時(shí)鏈接,僅用于文章預(yù)覽,將在時(shí)失效
人工智能開發(fā)者 正文
發(fā)私信給隔壁王大喵
發(fā)送

0

老司機(jī)都開火箭了!Cython 助力 Python NLP 實(shí)現(xiàn)百倍加速

本文作者: 隔壁王大喵 編輯:汪思穎 2018-06-26 16:54
導(dǎo)語:本文介紹了如何利用 Cython 和 spaCy 讓 Python 在自然語言處理任務(wù)中獲得百倍加速,快來看看吧!

雷鋒網(wǎng) AI 研習(xí)社按:本文的作者是來自 Hugging face 的科學(xué)家 Thomas Wolf,他的研究方向包括機(jī)器學(xué)習(xí)、自然語言處理和深度學(xué)習(xí)。在這篇博客中,他介紹了如何利用 Cython 和 spaCy 讓 Python 在自然語言處理任務(wù)中獲得百倍加速。雷鋒網(wǎng) AI 研習(xí)社根據(jù)原文進(jìn)行了編譯。

老司機(jī)都開火箭了!Cython 助力 Python NLP 實(shí)現(xiàn)百倍加速

SpaceX 獵鷹重型發(fā)射器,版權(quán)歸 SpaceX 所有

提示:本文中涉及的所有例子都可以在這個(gè) Jupyter notebook 中獲得源碼。

在去年我們發(fā)布了用 Python 實(shí)現(xiàn)的基于神經(jīng)網(wǎng)絡(luò)的相互引用解析包(Neural coreference resolution package)之后,在社區(qū)中獲得了驚人數(shù)量的反饋,許多人開始將該解析包用到各種各樣的應(yīng)用中,有一些應(yīng)用場景甚至已經(jīng)超出了我們原本設(shè)計(jì)的對(duì)話框用例(Dialog use-case)。

后來我們發(fā)現(xiàn),雖然這個(gè)解析包對(duì)于對(duì)話框消息而言,解析速度完全夠用,但如果要解析更大篇幅的文章就顯得太慢了。

因此我決定要深入探索解決方案,并最終開發(fā)出了 NeuralCoref v3.0。這個(gè)版本比之前(每秒解析幾千字)的要快出百倍,同時(shí)還保證了相同的準(zhǔn)確性,當(dāng)然,它依然易于使用,也符合 Python 庫的生態(tài)環(huán)境。

在本篇文章中,我想向大家分享我在開發(fā) NeuralCoref v3.0 過程中學(xué)到的一些經(jīng)驗(yàn),尤其將涉及:

  • 如何才能夠使用 Python 設(shè)計(jì)出一個(gè)高效率的模塊,

  • 如何利用好 spaCy 的內(nèi)置數(shù)據(jù)結(jié)構(gòu),從而設(shè)計(jì)出超高效的自然語言處理函數(shù)。

我的標(biāo)題其實(shí)有點(diǎn)作弊,因?yàn)槲覍?shí)際上要談?wù)摰氖?Python,同時(shí)也要介紹一些 Cython 的特性。不過你知道嗎?Cython 屬于 Python 的超集,所以不要讓它嚇跑了!

小提示:你當(dāng)前所編寫的 Python 項(xiàng)目已經(jīng)算是一個(gè) Cython 項(xiàng)目了。

以下給出了一些可能需要采用這種加速策略的場景:

  • 你正在使用 Python 給自然語言處理任務(wù)開發(fā)一個(gè)應(yīng)用級(jí)模塊

  • 你正在使用 Python 分析一個(gè)自然語言處理任務(wù)的大型數(shù)據(jù)集

  • 你正在為諸如 PyTorch/TensoFlow 這些深度學(xué)習(xí)框架預(yù)處理大型訓(xùn)練集,或者你的深度學(xué)習(xí)模型采用了處理邏輯復(fù)雜的批量加載器(Batch loader),它嚴(yán)重拖慢了你的訓(xùn)練速度

提示:我還發(fā)布了一個(gè) Jupyter notebook,其中包含了本文中討論的所有示例,歡迎大家下載調(diào)試!

百倍加速第一步:代碼剖析

老司機(jī)都開火箭了!Cython 助力 Python NLP 實(shí)現(xiàn)百倍加速

你需要知道的第一件事情是,你的大部分代碼在純 Python 環(huán)境下可能都運(yùn)行良好,但是其中存在一些瓶頸函數(shù)(Bottlenecks functions),一旦你能給予它們更多的「關(guān)照」,你的程序?qū)@得幾個(gè)數(shù)量級(jí)的提速。

所以你應(yīng)該從剖析自己的 Python 代碼開始,找出那些低效模塊。其中一種方法就是使用 cProfile

import cProfile

import pstats

import my_slow_module

cProfile.run('my_slow_module.run()', 'restats')

p = pstats.Stats('restats')

p.sort_stats('cumulative').print_stats(30)

你很可能會(huì)發(fā)現(xiàn)低效的原因是因?yàn)橐恍┭h(huán)控制,或者你使用神經(jīng)網(wǎng)絡(luò)時(shí)引入了過多的 Numpy 數(shù)組操作(我不會(huì)花費(fèi)時(shí)間在這里介紹 Numpy,這個(gè)問題已經(jīng)有太多文章進(jìn)行了討論)。

那么我們該如何來加速循環(huán)呢?

在 Pyhthon 中加入 Cython 加速循環(huán)計(jì)算

老司機(jī)都開火箭了!Cython 助力 Python NLP 實(shí)現(xiàn)百倍加速

讓我們通過一個(gè)簡單的例子來解決這個(gè)問題。假設(shè)有一堆矩形,我們將它們存儲(chǔ)成一個(gè)由 Python 對(duì)象(例如 Rectangle 對(duì)象實(shí)例)構(gòu)成的列表。我們的模塊的主要功能是對(duì)該列表進(jìn)行迭代運(yùn)算,從而統(tǒng)計(jì)出有多少個(gè)矩形的面積是大于所設(shè)定閾值的。

我們的 Python 模塊非常簡單:

from random import random


class Rectangle:    

    def __init__(self, w, h):        

        self.w = w        

        self.h = h    

    def area(self):        

        return self.w * self.h


    def check_rectangles(rectangles, threshold):    

        n_out = 0    

        for rectangle in rectangles:        

            if rectangle.area() > threshold:            

                n_out += 1    

        return n_out


def main():    

    n_rectangles = 10000000    

    rectangles = list(Rectangle(random(), random()) for i in range(n_rectangles))    

    n_out = check_rectangles(rectangles, threshold=0.25)    

    print(n_out)

其中 check_rectangles 函數(shù)就是我們程序的瓶頸!它對(duì)一個(gè)很長的 Python 對(duì)象列表進(jìn)行迭代,而這一過程會(huì)相當(dāng)緩慢,因?yàn)?Python 解釋器在每次迭代中都需要做很多工作(查找類中的 area 方法、參數(shù)的打包和解包、調(diào)用 Python API 等等)。

這時(shí)候該有請 Cython 出場幫助我們加速循環(huán)操作了。

Cython 語言是 Python 的一個(gè)超集,它包含有兩種類型的對(duì)象:

  • Python 對(duì)象就是我們在常規(guī) Python 中使用到的那些對(duì)象,諸如數(shù)值、字符串、列表和類實(shí)例等等

  • Cython C 對(duì)象就是那些 C 和 C++ 對(duì)象,諸如雙精度、整型、浮點(diǎn)數(shù)、結(jié)構(gòu)和向量,它們能夠由 Cython 在超級(jí)高效的低級(jí)語言代碼中進(jìn)行編譯

該循環(huán)只要采用 Cython 進(jìn)行復(fù)現(xiàn)就能獲得更高的執(zhí)行速度,不過在 Cython 中我們只能夠操作 Cython C 對(duì)象。

定義這種循環(huán)最直接的一種方法就是,定義一個(gè)包含有計(jì)算過程中我們所需要用到的所有對(duì)象的結(jié)構(gòu)體。具體而言,在本例中就是矩形的長度和寬度。

然后我們可以將矩形對(duì)象列表存儲(chǔ)到 C 的結(jié)構(gòu)數(shù)組中,再將數(shù)組傳遞給 check_rectangles 函數(shù)。這個(gè)函數(shù)現(xiàn)在將接收一個(gè) C 數(shù)組作為輸入,此外我們還使用 cdef 關(guān)鍵字取代了 def(注意:cdef 也可以用于定義 Cython C 對(duì)象)將函數(shù)定義為一個(gè) Cython 函數(shù)。 

這里是 Cython 版本的模塊程序:

from cymem.cymem cimport Pool

from random import random


cdef struct Rectangle:    

    float w    

    float h


cdef int check_rectangles(Rectangle* rectangles, int n_rectangles, float threshold):    

    cdef int n_out = 0    

    # C arrays contain no size information => we need to give it explicitly    

    for rectangle in rectangles[:n_rectangles]:        

        if rectangle[i].w * rectangle[i].h > threshold:            

            n_out += 1    

    return n_out


def main():    

    cdef:        

        int n_rectangles = 10000000        

        float threshold = 0.25        

        Pool mem = Pool()        

        Rectangle* rectangles = <Rectangle*>mem.alloc(n_rectangles, sizeof(Rectangle))    

    for i in range(n_rectangles):        

        rectangles[i].w = random()        

        rectangles[i].h = random()    

    n_out = check_rectangles(rectangles, n_rectangles, threshold)

    print(n_out)

這里我們使用了原生的 C 數(shù)組指針,不過你還有其它選擇,特別是 C++ 中諸如向量、二元組、隊(duì)列這樣的結(jié)構(gòu)體。在這段程序中,我還使用了一個(gè)來自 cymem 提供的 Pool() 內(nèi)存管理對(duì)象,它可以避免手動(dòng)釋放所申請的 C 數(shù)組內(nèi)存空間。當(dāng)不再需要使用 Pool 中的對(duì)象時(shí),它將自動(dòng)釋放該對(duì)象所占用的內(nèi)存空間。

補(bǔ)充:spaCy API 的 Cython 標(biāo)準(zhǔn)頁面提供了在實(shí)際應(yīng)用中使用 Cython 實(shí)現(xiàn)自然語言處理任務(wù)的參考資料。 

讓我們開始動(dòng)手吧!

有很多辦法來測試、編譯和發(fā)布 Cython 代碼。Cython 甚至可以像 Python 一樣直接用于 Jupyter Notebook 中。

通過 pip install cython 命令安裝 Cython。

老司機(jī)都開火箭了!Cython 助力 Python NLP 實(shí)現(xiàn)百倍加速

首先在 Jupyter 中進(jìn)行測試

使用 %load_ext Cython 指令在 Jupyter notebook 中加載 Cython 擴(kuò)展。

然后通過指令 %%cython,我們就可以像 Python 一樣在 Jupyter notebook 中使用 Cython。

如果在執(zhí)行 Cython 代碼的時(shí)候遇到了編譯錯(cuò)誤,請檢查 Jupyter 終端的完整輸出信息。

大多數(shù)情況下可能都是因?yàn)樵?%%cython 之后遺漏了 -+ 標(biāo)簽(比如當(dāng)你使用 spaCy Cython 接口時(shí))。如果編譯器報(bào)出了關(guān)于 Numpy 的錯(cuò)誤,那就是遺漏了 import numpy。

正如我在一開始就提到的,請好好閱讀這份 Jupyter notebook 和這篇文章,它包含了我們在 Jupyter 中討論到的所有示例。

編寫、使用和發(fā)布 Cython 代碼

Cython 代碼的文件后綴是 .pyx,這些文件將被 Cython 編譯器編譯成 C 或 C++ 文件,再進(jìn)一步地被 C 編譯器編譯成字節(jié)碼文件。最終 Python 解釋器將能夠調(diào)用這些字節(jié)碼文件。

你也可以使用 pyximport 將一個(gè) .pyx 文件直接加載到 Python 程序中:

>>> import pyximport; pyximport.install()

>>> import my_cython_module

你也可以將自己的 Cython 代碼作為 Python 包構(gòu)建,然后像正常的 Python 包一樣將其導(dǎo)入或者發(fā)布,更多細(xì)節(jié)請參考這里。不過這種做法需要花費(fèi)更多的時(shí)間,特別是你需要讓 Cython 包能夠在所有的平臺(tái)上運(yùn)行。如果你需要一個(gè)參考樣例,不妨看看 spaCy 的安裝腳本

在我們開始優(yōu)化自然語言處理任務(wù)之前,還是先快速介紹一下 def、cdefcpdef 這三個(gè)關(guān)鍵字。它們是你開始學(xué)會(huì)使用 Cython 之前需要掌握的最主要的知識(shí)。

你可以在 Cython 程序中使用三種類型的函數(shù):

  • Python 函數(shù)由 def 關(guān)鍵字定義,它的輸入和輸出都是 Python 對(duì)象。在函數(shù)內(nèi)可以使用 Python 和 C/C++ 對(duì)象,并且能夠調(diào)用 Cython 和 Python 函數(shù)。

  • Cython 函數(shù)由 cdef 關(guān)鍵字進(jìn)行定義,它可以作為輸入對(duì)象,在函數(shù)內(nèi)部也可以操作或者輸出 Python 和 C/C++ 對(duì)象。這些函數(shù)不能從 Python 環(huán)境中訪問(即 Python 解釋器和其它可以導(dǎo)入 Cython 模塊的純 Python 模塊),但是可以由其它 Cython 模塊進(jìn)行導(dǎo)入。

  • 通過關(guān)鍵字 cpdef 定義的 Cython 函數(shù)與 cdef 定義的 Cython 函數(shù)很相似,但是 cpdef 定義的函數(shù)同時(shí)還提供了 Python 裝飾器,所以它們能夠在 Python 環(huán)境中被直接調(diào)用(函數(shù)采用 Python 對(duì)象作為輸入與輸出),此外也支持在 Cython 模塊中被調(diào)用(函數(shù)采用 C/C++ 或者 Python 對(duì)象作為輸入)。

cdef 關(guān)鍵字的另一個(gè)用途就是,在代碼中表明某一個(gè)對(duì)象是 Cython C/C++ 對(duì)象。所以除非你在代碼中使用 cdef 聲明對(duì)象,否則這些對(duì)象都會(huì)被解釋器當(dāng)做 Python 對(duì)象(這會(huì)導(dǎo)致訪問速度變慢)。

使用 Cython 和 spaCy 加速自然語言處理

這一切看起來都很好,但是......我們到現(xiàn)在都還沒開始涉及優(yōu)化自然語言處理任務(wù)!沒有字符串操作,沒有 unicode 編碼,也沒有我們在自然語言處理中所使用的妙招。

此外 Cython 的官方文檔甚至建議不要使用 C 語言類型的字符串:

通常來說:除非你明確地知道自己正在做什么,不然就該避免使用 C 類型字符串,而應(yīng)該使用 Python 的字符串對(duì)象。

那么當(dāng)我們在操作字符串時(shí),要如何在 Cython 中設(shè)計(jì)一個(gè)更加高效的循環(huán)呢?

spaCy 引起了我們的注意力。

spaCy 處理該問題的做法就非常地明智。

將所有的字符串轉(zhuǎn)換為 64 位哈希碼

spaCy 中所有的 unicode 字符串(一個(gè)標(biāo)記的文本、它的小寫形式文本、它的引理形式、POS 標(biāo)記標(biāo)簽、解析樹依賴標(biāo)簽、命名實(shí)體標(biāo)簽等等)都被存儲(chǔ)在一個(gè)稱為 StringStore 的數(shù)據(jù)結(jié)構(gòu)中,它通過一個(gè) 64 位哈希碼進(jìn)行索引,例如 C 類型的 uint64_t

老司機(jī)都開火箭了!Cython 助力 Python NLP 實(shí)現(xiàn)百倍加速

StringStore 對(duì)象實(shí)現(xiàn)了 Python unicode 字符串與 64 位哈希碼之前的查找映射。

它可以從 spaCy 的任何地方和任意對(duì)象進(jìn)行訪問,例如 npl.vocab.stringsdoc.vocab.strings 或者 span.doc.vocab.string。

當(dāng)某一個(gè)模塊需要在某些標(biāo)記(tokens)上獲得更快的處理速度時(shí),你可以使用 C 語言類型的 64 位哈希碼代替字符串來實(shí)現(xiàn)。調(diào)用 StringStore 查找表將返回與該哈希碼相關(guān)聯(lián)的 Python unicode 字符串。

但是 spaCy 能做的可不僅僅只有這些,它還允許我們訪問文檔和詞匯表完全填充的 C 語言類型結(jié)構(gòu),我們可以在 Cython 循環(huán)中使用這些結(jié)構(gòu),而不必去構(gòu)建自己的結(jié)構(gòu)。

SpaCy 的內(nèi)部數(shù)據(jù)結(jié)構(gòu)

與 spaCy 文檔有關(guān)的主要數(shù)據(jù)結(jié)構(gòu)是 Doc 對(duì)象,該對(duì)象擁有經(jīng)過處理的字符串的標(biāo)記序列(“words”)以及 C 語言類型對(duì)象中的所有標(biāo)注,稱為 doc.c,它是一個(gè) TokenC 的結(jié)構(gòu)數(shù)組。

TokenC 結(jié)構(gòu)包含了我們需要的關(guān)于每個(gè)標(biāo)記的所有信息。這種信息被存儲(chǔ)成 64 位哈希碼,它可以與我們剛剛所見到的 unicode 字符串進(jìn)行重新關(guān)聯(lián)。

如果想要準(zhǔn)確地了解這些漂亮的 C 結(jié)構(gòu)中的內(nèi)容,可以查看新建的 spaCy 的 Cython API 文檔。

接下來看一個(gè)簡單的自然語言處理的例子。

更快的自然語言處理

假設(shè)現(xiàn)在有一個(gè)文本文檔的數(shù)據(jù)集需要分析。

import urllib.request

import spacy


with urllib.request.urlopen('https://raw.githubusercontent.com/pytorch/examples/master/word_language_model/data/wikitext-2/valid.txt') as response:   

    text = response.read()

nlp = spacy.load('en')

doc_list = list(nlp(text[:800000].decode('utf8')) for i in range(10))

我寫了一個(gè)腳本用于創(chuàng)建一個(gè)包含有 10 份文檔的列表,每份文檔都大概含有 17 萬個(gè)單詞,采用 spaCy 進(jìn)行分析。當(dāng)然我們也可以對(duì) 17 萬份文檔(每份文檔包含 10 個(gè)單詞)進(jìn)行分析,但是這樣做會(huì)導(dǎo)致創(chuàng)建的過程非常慢,所以我們還是選擇了 10 份文檔。

我們想要在這個(gè)數(shù)據(jù)集上展開某些自然語言處理任務(wù)。例如,我們可以統(tǒng)計(jì)數(shù)據(jù)集中單詞「run」作為名詞出現(xiàn)的次數(shù)(例如,被 spaCy 標(biāo)記為「NN」詞性標(biāo)簽)。

采用 Python 循環(huán)來實(shí)現(xiàn)上述分析過程非常簡單和直觀:

def slow_loop(doc_list, word, tag):    

    n_out = 0    

    for doc in doc_list:        

        for tok in doc:            

            if tok.lower_ == word and tok.tag_ == tag:                

                n_out += 1    

     return n_out


def main_nlp_slow(doc_list):    

    n_out = slow_loop(doc_list, 'run', 'NN')    

    print(n_out)

但是這個(gè)版本的代碼運(yùn)行起來非常慢!這段代碼在我的筆記本上需要運(yùn)行 1.4 秒才能獲得答案。如果我們的數(shù)據(jù)集中包含有數(shù)以百萬計(jì)的文檔,為了獲得答案,我們也許需要花費(fèi)超過一天的時(shí)間。

我們也許能夠采用多線程來實(shí)現(xiàn)加速,但是在 Python 中這種做法并不是那么明智,因?yàn)槟氵€需要處理全局解釋器鎖(GIL)。另外請注意,Cython 也可以使用多線程!Cython 在后臺(tái)可以直接調(diào)用 OpenMP。不過我沒有時(shí)間在這里討論并行性,所以請查看此鏈接以了解更多詳情。

現(xiàn)在讓我們嘗試使用 spaCy 和 Cython 來加速 Python 代碼。

首先需要考慮好數(shù)據(jù)結(jié)構(gòu),我們需要一個(gè) C 類型的數(shù)組來存儲(chǔ)數(shù)據(jù),需要指針來指向每個(gè)文檔的 TokenC 數(shù)組。我們還需要將測試字符(「run」和「NN」)轉(zhuǎn)成 64 位哈希碼。

當(dāng)所有需要處理的數(shù)據(jù)都變成了 C 類型對(duì)象,我們就可以以純 C 語言的速度對(duì)數(shù)據(jù)集進(jìn)行迭代。

這里展示了這個(gè)例子被轉(zhuǎn)換成 Cython 和 spaCy 的實(shí)現(xiàn):

%%cython -+

import numpy # Sometime we have a fail to import numpy compilation error if we don't import numpy

from cymem.cymem cimport Pool

from spacy.tokens.doc cimport Doc

from spacy.typedefs cimport hash_t

from spacy.structs cimport TokenC


cdef struct DocElement:    

    TokenC* c    

    int length


cdef int fast_loop(DocElement* docs, int n_docs, hash_t word, hash_t tag):    

    cdef int n_out = 0    

    for doc in docs[:n_docs]:        

        for c in doc.c[:doc.length]:            

            if c.lex.lower == word and c.tag == tag:                

                n_out += 1    

    return n_out


def main_nlp_fast(doc_list):    

    cdef int i, n_out, n_docs = len(doc_list)    

    cdef Pool mem = Pool()    

    cdef DocElement* docs = <DocElement*>mem.alloc(n_docs, sizeof(DocElement))    

    cdef Doc doc    

    for i, doc in enumerate(doc_list): # Populate our database structure        

        docs[i].c = doc.c        

        docs[i].length = (<Doc>doc).length    

    word_hash = doc.vocab.strings.add('run')    

    tag_hash = doc.vocab.strings.add('NN')    

    n_out = fast_loop(docs, n_docs, word_hash, tag_hash)    

    print(n_out)

代碼有點(diǎn)長,因?yàn)槲覀儽仨氃谡{(diào)用 Cython 函數(shù)之前在 main_nlp_fast 中聲明和填充 C 結(jié)構(gòu)。

補(bǔ)充:如果你在代碼中需要多次使用低級(jí)結(jié)構(gòu),比每次填充 C 結(jié)構(gòu)更優(yōu)雅的做法是,使用 C 類型結(jié)構(gòu)的 Cython 擴(kuò)展類型裝飾器來設(shè)計(jì) Python 代碼。這就是大多數(shù) spaCy 代碼所采用的結(jié)構(gòu),它非常優(yōu)雅,兼具高效、低內(nèi)存花銷和易于訪問的特性。

這串代碼雖然變長了,但是運(yùn)行效率卻更高!在我的 Jupyter notebook上,這串 Cython 代碼只運(yùn)行了大概 20 毫秒,比之前的純 Python 循環(huán)快了大概 80 倍。

使用 Jupyter notebook 單元編寫模塊的速度很可觀,它可以與其它 Python 模塊和函數(shù)自然地連接:在 20 毫秒內(nèi)掃描大約 170 萬個(gè)單詞,這意味著我們每秒能夠處理高達(dá) 8 千萬個(gè)單詞。

對(duì)使用 Cython 進(jìn)行自然語言處理加速的介紹到此為止,希望大家能喜歡它。

關(guān)于 Cython 還有很多其它的東西可以介紹,但是已經(jīng)超出了這篇文章的初衷(這篇文章只是作為簡介)。從現(xiàn)在開始,最好的資料也許是這份綜述性的 Cython 教程和介紹 spaCy 自然語言處理的 Cython 頁面。

如果你還想要獲得更多類似的內(nèi)容,請記得給我們點(diǎn)贊喲!

Via 100 Times Faster Natural Language Processing in Python,雷鋒網(wǎng) AI 研習(xí)社編譯整理

雷峰網(wǎng)版權(quán)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知。

老司機(jī)都開火箭了!Cython 助力 Python NLP 實(shí)現(xiàn)百倍加速

分享:
相關(guān)文章

知情人士

我也是個(gè)旅途的浪人
當(dāng)月熱門文章
最新文章
請?zhí)顚懮暾埲速Y料
姓名
電話
郵箱
微信號(hào)
作品鏈接
個(gè)人簡介
為了您的賬戶安全,請驗(yàn)證郵箱
您的郵箱還未驗(yàn)證,完成可獲20積分喲!
請驗(yàn)證您的郵箱
立即驗(yàn)證
完善賬號(hào)信息
您的賬號(hào)已經(jīng)綁定,現(xiàn)在您可以設(shè)置密碼以方便用郵箱登錄
立即設(shè)置 以后再說