阿里云EasyNLP中文文圖生成模型帶你秒變藝術(shù)家
作者:汪誠(chéng)愚、劉婷婷
導(dǎo)讀
宣物莫大于言,存形莫善于畫(huà)。
--【晉】陸機(jī)
多模態(tài)數(shù)據(jù)(文本、圖像、聲音)是人類認(rèn)識(shí)、理解和表達(dá)世間萬(wàn)物的重要載體。近年來(lái),多模態(tài)數(shù)據(jù)的爆炸性增長(zhǎng)促進(jìn)了內(nèi)容互聯(lián)網(wǎng)的繁榮,也帶來(lái)了大量多模態(tài)內(nèi)容理解和生成的需求。與常見(jiàn)的跨模態(tài)理解任務(wù)不同,文到圖的生成任務(wù)是流行的跨模態(tài)生成任務(wù),旨在生成與給定文本對(duì)應(yīng)的圖像。這一文圖生成的任務(wù),極大地釋放了AI的想象力,也激發(fā)了人類的創(chuàng)意。典型的模型例如OpenAI開(kāi)發(fā)的DALL-E和DALL-E2。近期,業(yè)界也訓(xùn)練出了更大、更新的文圖生成模型,例如Google提出的Parti和Imagen。
然而,上述模型一般不能用于處理中文的需求,而且上述模型的參數(shù)量龐大,很難被開(kāi)源社區(qū)的廣大用戶直接用來(lái)Fine-tune和推理。本次,EasyNLP開(kāi)源框架再次迎來(lái)大升級(jí),集成了先進(jìn)的文圖生成架構(gòu)Transformer+VQGAN,同時(shí),向開(kāi)源社區(qū)免費(fèi)開(kāi)放不同參數(shù)量的中文文圖生成模型的Checkpoint,以及相應(yīng)Fine-tune和推理接口。用戶可以在我們開(kāi)放的Checkpoint基礎(chǔ)上進(jìn)行少量領(lǐng)域相關(guān)的微調(diào),在不消耗大量計(jì)算資源的情況下,就能一鍵進(jìn)行各種藝術(shù)創(chuàng)作。
EasyNLP是阿里云機(jī)器學(xué)習(xí)PAI 團(tuán)隊(duì)基于 PyTorch 開(kāi)發(fā)的易用且豐富的中文NLP算法框架,并且提供了從訓(xùn)練到部署的一站式 NLP 開(kāi)發(fā)體驗(yàn)。EasyNLP 提供了簡(jiǎn)潔的接口供用戶開(kāi)發(fā) NLP 模型,包括NLP應(yīng)用 AppZoo 、預(yù)訓(xùn)練模型 ModelZoo、數(shù)據(jù)倉(cāng)庫(kù)DataHub等特性。由于跨模態(tài)理解和生成需求的不斷增加,EasyNLP也支持各種跨模態(tài)模型,特別是中文領(lǐng)域的跨模態(tài)模型,推向開(kāi)源社區(qū)。例如,在先前的工作中,EasyNLP已經(jīng)對(duì)中文圖文檢索CLIP模型進(jìn)行了支持(看這里)。我們希望能夠服務(wù)更多的 NLP 和多模態(tài)算法開(kāi)發(fā)者和研究者,也希望和社區(qū)一起推動(dòng) NLP /多模態(tài)技術(shù)的發(fā)展和模型落地。本文簡(jiǎn)要介紹文圖生成的技術(shù),以及如何在EasyNLP框架中如何輕松實(shí)現(xiàn)文圖生成,帶你秒變藝術(shù)家。本文開(kāi)頭的展示圖片即為我們模型創(chuàng)作的作品。
文圖生成模型簡(jiǎn)述
下面以幾個(gè)經(jīng)典的基于Transformer的工作為例,簡(jiǎn)單介紹文圖生成模型的技術(shù)。DALL-E由OpenAI提出,采取兩階段的方法生成圖像。在第一階段,訓(xùn)練一個(gè)dVAE(discrete variational autoencoder)的模型將256×256的RGB圖片轉(zhuǎn)化為32×32的image token,這一步驟將圖片進(jìn)行信息壓縮和離散化,方便進(jìn)行文本到圖像的生成。第二階段,DALL-E訓(xùn)練一個(gè)自回歸的Transformer模型,將文本輸入轉(zhuǎn)化為上述1024個(gè)image token。
由清華大學(xué)等單位提出的CogView模型對(duì)上述兩階段文圖生成的過(guò)程進(jìn)行了進(jìn)一步的優(yōu)化。在下圖中,CogView采用了sentence piece作為text tokenizer使得輸入文本的空間表達(dá)更加豐富,并且在模型的Fine-tune過(guò)程中采用了多種技術(shù),例如圖像的超分、風(fēng)格遷移等。
ERNIE-ViLG模型考慮進(jìn)一步考慮了Transformer模型學(xué)習(xí)知識(shí)的可遷移性,同時(shí)學(xué)習(xí)了從文本生成圖像和從圖像生成文本這兩種任務(wù)。其架構(gòu)圖如下所示:
隨著文圖生成技術(shù)的不斷發(fā)展,新的模型和技術(shù)不斷涌現(xiàn)。舉例來(lái)說(shuō),OFA將多種跨模態(tài)的生成任務(wù)統(tǒng)一在同一個(gè)模型架構(gòu)中。DALL-E 2同樣由OpenAI提出,是DALL-E模型的升級(jí)版,考慮了層次化的圖像生成技術(shù),模型利用CLIP encoder作為編碼器,更好地融入了CLIP預(yù)訓(xùn)練的跨模態(tài)表征。Google進(jìn)一步提出了Diffusion Model的架構(gòu),能有效生成高清大圖,如下所示:
在本文中,我們不再對(duì)這些細(xì)節(jié)進(jìn)行贅述。感興趣的讀者可以進(jìn)一步查閱參考文獻(xiàn)。
EasyNLP文圖生成模型
由于前述模型的規(guī)模往往在數(shù)十億、百億參數(shù)級(jí)別,龐大的模型雖然能生成質(zhì)量較大的圖片,然后對(duì)計(jì)算資源和預(yù)訓(xùn)練數(shù)據(jù)的要求使得這些模型很難在開(kāi)源社區(qū)廣泛應(yīng)用,尤其在需要面向垂直領(lǐng)域的情況下。在本節(jié)中,我們?cè)敿?xì)介紹EasyNLP提供的中文文圖生成模型,它在較小參數(shù)量的情況下,依然具有良好的文圖生成效果。
模型架構(gòu)
模型框架圖如下圖所示:
考慮到Transformer模型復(fù)雜度隨序列長(zhǎng)度呈二次方增長(zhǎng),文圖生成模型的訓(xùn)練一般以圖像矢量量化和自回歸訓(xùn)練兩階段結(jié)合的方式進(jìn)行。
圖像矢量量化是指將圖像進(jìn)行離散化編碼,如將256×256的RGB圖像進(jìn)行16倍降采樣,得到16×16的離散化序列,序列中的每個(gè)image token對(duì)應(yīng)于codebook中的表示。常見(jiàn)的圖像矢量量化方法包括:VQVAE、VQVAE-2和VQGAN等。我們采用VQGAN在ImageNet上訓(xùn)練的f16_16384(16倍降采樣,詞表大小為16384)的模型權(quán)重來(lái)生成圖像的離散化序列。
自回歸訓(xùn)練是指將文本序列和圖像序列作為輸入,在圖像部分,每個(gè)image token僅與文本序列的tokens和其之前的image tokens進(jìn)行attention計(jì)算。我們采用GPT作為backbone,能夠適應(yīng)不同模型規(guī)模的生成任務(wù)。在模型預(yù)測(cè)階段,輸入文本序列,模型以自回歸的方式逐步生成定長(zhǎng)的圖像序列,再通過(guò)VQGAN decoder重構(gòu)為圖像。
開(kāi)源模型參數(shù)設(shè)置
在EasyNLP中,我們提供兩個(gè)版本的中文文圖生成模型,模型參數(shù)配置如下表:
模型實(shí)現(xiàn)
在EasyNLP框架中,我們?cè)谀P蛯訕?gòu)建基于minGPT的backbone構(gòu)建模型,核心部分如下所示:
self.first_stage_model = VQModel(ckpt_path=vqgan_ckpt_path).eval()
self.transformer = GPT(self.config)
VQModel的Encoding階段過(guò)程為:
# in easynlp/appzoo/text2image_generation/model.py
@torch.no_grad()
def encode_to_z(self, x):
quant_z, _, info = self.first_stage_model.encode(x)
indices = info[2].view(quant_z.shape[0], -1)
return quant_z, indices
x = inputs['image']
x = x.permute(0, 3, 1, 2).to(memory_format=torch.contiguous_format)
# one step to produce the logits
_, z_indices = self.encode_to_z(x) # z_indice: torch.Size([batch_size, 256])
VQModel的Decoding階段過(guò)程為:
# in easynlp/appzoo/text2image_generation/model.py
@torch.no_grad()
def decode_to_img(self, index, zshape):
bhwc = (zshape[0],zshape[2],zshape[3],zshape[1])
quant_z = self.first_stage_model.quantize.get_codebook_entry(
index.reshape(-1), shape=bhwc)
x = self.first_stage_model.decode(quant_z)
return x
# sample為訓(xùn)練階段的結(jié)果生成,與預(yù)測(cè)階段的generate類似,詳解見(jiàn)下文generate
index_sample = self.sample(z_start_indices, c_indices,
steps=z_indices.shape[1],
...)
x_sample = self.decode_to_img(index_sample, quant_z.shape)
Transformer采用minGPT進(jìn)行構(gòu)建,輸入圖像的離散編碼,輸出文本token。前向傳播過(guò)程為:
# in easynlp/appzoo/text2image_generation/model.py
def forward(self, inputs):
x = inputs['image']
c = inputs['text']
x = x.permute(0, 3, 1, 2).to(memory_format=torch.contiguous_format)
# one step to produce the logits
_, z_indices = self.encode_to_z(x) # z_indice: torch.Size([batch_size, 256])
c_indices = c
if self.training and self.pkeep < 1.0:
mask = torch.bernoulli(self.pkeep*torch.ones(z_indices.shape,
device=z_indices.device))
mask = mask.round().to(dtype=torch.int64)
r_indices = torch.randint_like(z_indices, self.transformer.config.vocab_size)
a_indices = mask*z_indices+(1-mask)*r_indices
else:
a_indices = z_indices
cz_indices = torch.cat((c_indices, a_indices), dim=1)
# target includes all sequence elements (no need to handle first one
# differently because we are conditioning)
target = z_indices
# make the prediction
logits, _ = self.transformer(cz_indices[:, :-1])
# cut off conditioning outputs - output i corresponds to p(z_i | z_{<i}, c)
logits = logits[:, c_indices.shape[1]-1:]
return logits, target
在預(yù)測(cè)階段,輸入為文本token, 輸出為256*256的圖像。首先,將輸入文本預(yù)處理為token序列:
# in easynlp/appzoo/text2image_generation/predictor.py
def preprocess(self, in_data):
if not in_data:
raise RuntimeError("Input data should not be None.")
if not isinstance(in_data, list):
in_data = [in_data]
rst = {"idx": [], "input_ids": []}
max_seq_length = -1
for record in in_data:
if "sequence_length" not in record:
break
max_seq_length = max(max_seq_length, record["sequence_length"])
max_seq_length = self.sequence_length if (max_seq_length == -1) else max_seq_length
for record in in_data:
text= record[self.first_sequence]
try:
self.MUTEX.acquire()
text_ids = self.tokenizer.convert_tokens_to_ids(self.tokenizer.tokenize(text))
text_ids = text_ids[: self.text_len]
n_pad = self.text_len - len(text_ids)
text_ids += [self.pad_id] * n_pad
text_ids = np.array(text_ids) + self.img_vocab_size
finally:
self.MUTEX.release()
rst["idx"].append(record["idx"])
rst["input_ids"].append(text_ids)
return rst
逐步生成長(zhǎng)度為16*16的圖像離散token序列:
# in easynlp/appzoo/text2image_generation/model.py
def generate(self, inputs, top_k=100, temperature=1.0):
cidx = inputs
sample = True
steps = 256
for k in range(steps):
x_cond = cidx
logits, _ = self.transformer(x_cond)
# pluck the logits at the final step and scale by temperature
logits = logits[:, -1, :] / temperature
# optionally crop probabilities to only the top k options
if top_k is not None:
logits = self.top_k_logits(logits, top_k)
# apply softmax to convert to probabilities
probs = torch.nn.functional.softmax(logits, dim=-1)
# sample from the distribution or take the most likely
if sample:
ix = torch.multinomial(probs, num_samples=1)
else:
_, ix = torch.topk(probs, k=1, dim=-1)
# append to the sequence and continue
cidx = torch.cat((cidx, ix), dim=1)
img_idx = cidx[:, 32:]
return img_idx
最后,我們調(diào)用VQModel的Decoding過(guò)程將這些圖像離散token序列轉(zhuǎn)換為圖像。
模型效果
我們?cè)谒膫€(gè)中文的公開(kāi)數(shù)據(jù)集COCO-CN、MUGE、Flickr8k-CN、Flickr30k-CN上驗(yàn)證了EasyNLP框架中文圖生成模型的效果。同時(shí),我們對(duì)比了這個(gè)模型和CogView、DALL-E的效果,如下所示:
其中,
1)MUGE是天池平臺(tái)公布的電商場(chǎng)景的中文大規(guī)模多模態(tài)評(píng)測(cè)基準(zhǔn)(http://tianchi.aliyun.com/muge)。為了方便計(jì)算指標(biāo),MUGE我們采用valid數(shù)據(jù)集的結(jié)果,其他數(shù)據(jù)集采用test數(shù)據(jù)集的結(jié)果。
2)CogView源自https://github.com/THUDM/CogView
3)DALL-E模型沒(méi)有公開(kāi)的官方代碼。已經(jīng)公開(kāi)的部分只包含VQVAE的代碼,不包括Transformer部分。我們基于廣受關(guān)注的https://github.com/lucidrains/DALLE-pytorch版本的代碼和該版本推薦的checkpoits進(jìn)行復(fù)現(xiàn),checkpoints為2.09億參數(shù),為OpenAI的DALL-E模型參數(shù)量的1/100。(OpenAI版本DALL-E為120億參數(shù),其中CLIP為4億參數(shù))。
經(jīng)典案例
我們分別在自然風(fēng)景數(shù)據(jù)集COCO-CN上Fine-tune了base和large級(jí)別的模型,如下展示了模型的效果:
示例1:一只俏皮的狗正跑過(guò)草地
示例2:一片水域的景色以日落為背景
我們也積累了阿里集團(tuán)的海量電商商品數(shù)據(jù),微調(diào)得到了面向電商商品的文圖生成模型。效果如下:
示例3:女童套頭毛衣打底衫秋冬針織衫童裝兒童內(nèi)搭上衣
示例4:春夏真皮工作鞋女深色軟皮久站舒適上班面試職業(yè)皮鞋
除了支持特定領(lǐng)域的應(yīng)用,文圖生成也極大地輔助了人類的藝術(shù)創(chuàng)作。使用訓(xùn)練得到的模型,我們可以秒變“中國(guó)國(guó)畫(huà)藝術(shù)大師”,示例如下所示:
更多的示例請(qǐng)欣賞:
使用教程
欣賞了模型生成的作品之后,如果我們想DIY,訓(xùn)練自己的文圖生成模型,應(yīng)該如何進(jìn)行呢?以下我們簡(jiǎn)要介紹在EasyNLP框架對(duì)預(yù)訓(xùn)練的文圖生成模型進(jìn)行Fine-tune和推理。
安裝EasyNLP
用戶可以直接參考鏈接的說(shuō)明安裝EasyNLP算法框架。
數(shù)據(jù)準(zhǔn)備
首先準(zhǔn)備訓(xùn)練數(shù)據(jù)與驗(yàn)證數(shù)據(jù),為tsv文件。這一文件包含以制表符\t分隔的兩列,第一列為索引號(hào),第二列為文本,第三列為圖片的base64編碼。用于測(cè)試的輸入文件為兩列,僅包含索引號(hào)和文本。
為了方便開(kāi)發(fā)者,我們也提供了轉(zhuǎn)換圖片到base64編碼的示例代碼:
import base64
from io import BytesIO
from PIL import Image
img = Image.open(fn)
img_buffer = BytesIO()
img.save(img_buffer, format=img.format)
byte_data = img_buffer.getvalue()
base64_str = base64.b64encode(byte_data) # bytes
下列文件已經(jīng)完成預(yù)處理,可用于測(cè)試:
# train
https://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/tutorials/painter_text2image/MUGE_train_text_imgbase64.tsv
# valid
https://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/tutorials/painter_text2image/MUGE_val_text_imgbase64.tsv
# test
https://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/tutorials/painter_text2image/MUGE_test.text.tsv
模型訓(xùn)練
我們采用以下命令對(duì)模型進(jìn)行fine-tune:
easynlp \
--mode=train \
--worker_gpu=1 \
--tables=MUGE_val_text_imgbase64.tsv,MUGE_val_text_imgbase64.tsv \
--input_schema=idx:str:1,text:str:1,imgbase64:str:1 \
--first_sequence=text \
--second_sequence=imgbase64 \
--checkpoint_dir=./finetuned_model/ \
--learning_rate=4e-5 \
--epoch_num=1 \
--random_seed=42 \
--logging_steps=100 \
--save_checkpoint_steps=1000 \
--sequence_length=288 \
--micro_batch_size=16 \
--app_name=text2image_generation \
--user_defined_parameters='
pretrain_model_name_or_path=alibaba-pai/pai-painter-large-zh
size=256
text_len=32
img_len=256
img_vocab_size=16384
'
我們提供base和large兩個(gè)版本的預(yù)訓(xùn)練模型,pretrain_model_name_or_path
分別為alibaba-pai/pai-painter-base-zh和alibaba-pai/pai-painter-large-zh。
訓(xùn)練完成后模型被保存到./finetuned_model/。
模型批量推理
模型訓(xùn)練完畢后,我們可以將其用于圖像生成,其示例如下:
easynlp \
--mode=predict \
--worker_gpu=1 \
--tables=MUGE_test.text.tsv \
--input_schema=idx:str:1,text:str:1 \
--first_sequence=text \
--outputs=./T2I_outputs.tsv \
--output_schema=idx,text,gen_imgbase64 \
--checkpoint_dir=./finetuned_model/ \
--sequence_length=288 \
--micro_batch_size=8 \
--app_name=text2image_generation \
--user_defined_parameters='
size=256
text_len=32
img_len=256
img_vocab_size=16384
'
結(jié)果存儲(chǔ)在一個(gè)tsv文件中,每行對(duì)應(yīng)輸入中的一個(gè)文本,輸出的圖像以base64編碼。
使用Pipeline接口快速體驗(yàn)文圖生成效果
為了進(jìn)一步方便開(kāi)發(fā)者使用,我們?cè)贓asyNLP框架內(nèi)也實(shí)現(xiàn)了Inference Pipeline功能。用戶可以使用如下命令調(diào)用Fine-tune過(guò)的電商場(chǎng)景下的文圖生成模型:
# 直接構(gòu)建pipeline
default_ecommercial_pipeline = pipeline("pai-painter-commercial-base-zh")
# 模型預(yù)測(cè)
data = ["寬松T恤"]
results = default_ecommercial_pipeline(data) # results的每一條是生成圖像的base64編碼
# base64轉(zhuǎn)換為圖像
def base64_to_image(imgbase64_str):
image = Image.open(BytesIO(base64.urlsafe_b64decode(imgbase64_str)))
return image
# 保存以文本命名的圖像
for text, result in zip(data, results):
imgpath = '{}.png'.format(text)
imgbase64_str = result['gen_imgbase64']
image = base64_to_image(imgbase64_str)
image.save(imgpath)
print('text: {}, save generated image: {}'.format(text, imgpath))
除了電商場(chǎng)景,我們還提供了以下場(chǎng)景的模型:
自然風(fēng)光場(chǎng)景:“pai-painter-scenery-base-zh”中國(guó)山水畫(huà)場(chǎng)景:“pai-painter-painting-base-zh”
在上面的代碼當(dāng)中替換“pai-painter-commercial-base-zh”,就可以直接體驗(yàn),歡迎試用。
對(duì)于用戶Fine-tune的文圖生成模型,我們也開(kāi)放了自定義模型加載的Pipeline接口:
# 加載模型,構(gòu)建pipeline
local_model_path = ...
text_to_image_pipeline = pipeline("text2image_generation", local_model_path)
# 模型預(yù)測(cè)
data = ["xxxx"]
results = text_to_image_pipeline(data) # results的每一條是生成圖像的base64編碼
未來(lái)展望
在這一期的工作中,我們?cè)贓asyNLP框架中集成了中文文圖生成功能,同時(shí)開(kāi)放了模型的Checkpoint,方便開(kāi)源社區(qū)用戶在資源有限情況下進(jìn)行少量領(lǐng)域相關(guān)的微調(diào),進(jìn)行各種藝術(shù)創(chuàng)作。在未來(lái),我們計(jì)劃在EasyNLP框架中推出更多相關(guān)模型,敬請(qǐng)期待。我們也將在EasyNLP框架中集成更多SOTA模型(特別是中文模型),來(lái)支持各種NLP和多模態(tài)任務(wù)。此外,阿里云機(jī)器學(xué)習(xí)PAI團(tuán)隊(duì)也在持續(xù)推進(jìn)中文多模態(tài)模型的自研工作,歡迎用戶持續(xù)關(guān)注我們,也歡迎加入我們的開(kāi)源社區(qū),共建中文NLP和多模態(tài)算法庫(kù)!
Github地址:https://github.com/alibaba/EasyNLP
Reference
1.Chengyu Wang, Minghui Qiu, Taolin Zhang, Tingting Liu, Lei Li, Jianing Wang, Ming Wang, Jun Huang, Wei Lin. EasyNLP: A Comprehensive and Easy-to-use Toolkit for Natural Language Processing. arXiv
2.Aditya Ramesh, Mikhail Pavlov, Gabriel Goh, Scott Gray, Chelsea Voss, Alec Radford, Mark Chen, Ilya Sutskever. Zero-Shot Text-to-Image Generation. ICML 2021: 8821-8831
3.Ming Ding, Zhuoyi Yang, Wenyi Hong, Wendi Zheng, Chang Zhou, Da Yin, Junyang Lin, Xu Zou, Zhou Shao, Hongxia Yang, Jie Tang. CogView: Mastering Text-to-Image Generation via Transformers. NeurIPS 2021: 19822-19835
4.Han Zhang, Weichong Yin, Yewei Fang, Lanxin Li, Boqiang Duan, Zhihua Wu, Yu Sun, Hao Tian, Hua Wu, Haifeng Wang. ERNIE-ViLG: Unified Generative Pre-training for Bidirectional Vision-Language Generation. arXiv
5.Peng Wang, An Yang, Rui Men, Junyang Lin, Shuai Bai, Zhikang Li, Jianxin Ma, Chang Zhou, Jingren Zhou, Hongxia Yang. Unifying Architectures, Tasks, and Modalities Through a Simple Sequence-to-Sequence Learning Framework. ICML 2022
6.Aditya Ramesh, Prafulla Dhariwal, Alex Nichol, Casey Chu, Mark Chen. Hierarchical Text-Conditional Image Generation with CLIP Latents. arXiv
7.Van Den Oord A, Vinyals O. Neural discrete representation learning. NIPS 2017
8.Esser P, Rombach R, Ommer B. Taming transformers for high-resolution image synthesis. CVPR 2021: 12873-12883.
9.Chitwan Saharia, William Chan, Saurabh Saxena, Lala Li, Jay Whang, Emily Denton, Seyed Kamyar Seyed Ghasemipour, Burcu Karagol Ayan, S. Sara Mahdavi, Rapha Gontijo Lopes, Tim Salimans, Jonathan Ho, David J. Fleet, Mohammad Norouzi: Photorealistic Text-to-Image Diffusion Models with Deep Language Understanding. arXiv
10.Jiahui Yu, Yuanzhong Xu, Jing Yu Koh, Thang Luong, Gunjan Baid, Zirui Wang, Vijay Vasudevan, Alexander Ku, Yinfei Yang, Burcu Karagol Ayan, Ben Hutchinson, Wei Han, Zarana Parekh, Xin Li, Han Zhang, Jason Baldridge, Yonghui Wu. Scaling Autoregressive Models for Content-Rich Text-to-Image Generation. arXiv
本站所有文章、數(shù)據(jù)、圖片均來(lái)自互聯(lián)網(wǎng),一切版權(quán)均歸源網(wǎng)站或源作者所有。
如果侵犯了你的權(quán)益請(qǐng)來(lái)信告知我們刪除。郵箱:business@qudong.com